Vue+Jwt+SpringBoot+Ldap完成登录认证的示例代码

时间:2021-05-26

本人野生程序员一名,了解了一些微服务架构、前后端分离、SPA的知识后就想试试做点什么东西。之前一直做后端,前端只是有基础知识。之前学习过angularjs,但当时就是一脸懵逼(完全看不懂是啥)就放弃了。最近又学了Vue,这次感觉总算明白了一些,但其中也跳过很多坑(应该还会更多),在这里写下来记录一下吧。

说回主题,之前传统登录认证的方法基本是由服务器端提供一个登录页面,页面中的一个form输入username和password后POST给服务器,服务器将这些信息与DB或Ldap中的用户信息对比,成功则将这个用户信息记录到session中。

这里我就跳了第一个大坑。传统方式前后端不分离,后端负责页面渲染,但是在前后分离的情况下,后端只负责通过暴露的RestApi提供数据,而页面的渲染、路由都由前端完成。因为rest是无状态的,因此也就不会有session记录到服务器端。

之前一直使用SpringSecurity+Cas+Ldap来做SSO,但是使用Vue做前端后我怎都想不出用之前的方法做SSO(这个坑真的爬了好久才爬出来)。后来终于想明白了上面说的session的问题(我是这么认为的也可能不对,CAS也有RestApi,但是按官网配置没成功,放弃了)。

第一个问题,该如何解决SSO的问题呢,要说到JWT。JWT是个规范,各种语言有各种语言的实现,可以去官网查到。我浅薄的理解是有一个认证服务(你自己写的,Db、Ldap什么都可以)这个认证服务会通过用户的提交信息判断认证是否成功,如果成功则查询出一些用户的信息(用户名、角色什么的),然后JWT把这些信息加密成为一个token,返回给客户端浏览器,浏览器把这些信息存储在localstorage中,以后每次访问资源都会在header中携带这个信息,服务器收到请求后使用和加密时相同的key解密密文,如果解密成功则视为用户已经认证过(当然你可以在加密时添加以一个过期时间)也就完成了SSO。使用解密出的角色信息你就可以判断这个用户是否有权限执行一些业务。这样做完后感觉好像SpringSecurity、Cas在SPA应用中的SSO似乎没什么作用了,目前我是这么认为的(当然可能不对)

第一个问题差不多解决了,来说第二个问题。之前因为有session的存在,在访问受保护的资源时如果服务器端没有当前用户的session,则会强制跳转到登录页。那在前后分离的情况下要如何实现这个需求。思路是这样的:利用Vue-Router的全局路由钩子,在访问任何页面时先判断localStorage中是否存在JWT加密后的token并且token是否过期,如果存在且没有过期则正常跳转到请求的页面,不存在或者过期则跳转到登录页重新认证。

思路说完了,上代码

1.首先你需要一个Ldap,我使用的是AD。这里我建立了一个叫minibox.com的域,并且添加了一个Employees的OU,其中有2个子OU,子OU中创建了2个用户。

在Groups中新建一些组,把之前创建的用户加入到组中,这样用户就拥有了角色。

2.搭建SpringBoot环境

2.1pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://</span> </div> <div class="input-group form-group has-feedback"> <span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span> <input v-model="password" type="password" class="form-control" placeholder="Password"> </div> <div class="row"> <div class="col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3"> <transition name="slide-fade"> <p v-if="show">用户名或密码错误</p> </transition> </div> </div> <div class="row"> <div class="col-sm-6 col-sm-offset-3 col-md-6 col-md-offset-3"> <button v-on:click="auth" class="btn btn-primary btn-block btn-flat">Sign In</button> </div> </div> </div> </div></template><script> //提供认证服务的restApi var authUrl = 'https://192.168.227.1:8443/auth' export default { name: 'app', data() { return { username: '', password: '', show: false } }, methods: { auth: function(){ var credentials = { username:this.username, password:this.password } this.$http.post(authUrl, credentials).then(response => { localStorage.token = response.data.token localStorage.tokenExpired = response.data.tokenExpired localStorage.userDisplayName = response.data.displayName this.$router.push('hello') }, response => { this.show = true }) } } }</script><style scoped> p{ text-align: center } .slide-fade-enter-active { transition: all .8s ease; } .slide-fade-leave-active { transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0); } .slide-fade-enter, .slide-fade-leave-to { transform: translateX(10px); opacity: 0; } @import '../assets/css/AdminLTE.min.css'</style>

5效果

5.1访问http://localhost:8000时被导航到登录页

5.2提交登录信息并取得token,跳转下一页

到这里整个功能就完成了。本人也是菜鸟一枚,理解有错误的地方还请各位老师指正。打算把整个分布式系统的开发过程记录下来。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章