SpringBoot+Vue+JWT的前后端分離登錄認(rèn)證詳細(xì)步驟
前后端分離的概念在現(xiàn)在很火,最近也學(xué)習(xí)了一下前后端分離的登錄認(rèn)證。
創(chuàng)建后端springboot工程
這個(gè)很簡(jiǎn)單了,按照idea的一步一步創(chuàng)建就行
文件目錄結(jié)構(gòu):
pom文件依賴(lài)導(dǎo)入。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.16</version> <scope>provided</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-core</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>javax.activation</groupId> <artifactId>activation</artifactId> <version>1.1.1</version> </dependency> </dependencies>
創(chuàng)建實(shí)體類(lèi):User
//username,password,token三個(gè)字段
private String username; private String password; private String token; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getToken() { return token; } public void setToken(String token) { this.token = token; }
創(chuàng)建JWToken
public class JwtToken { private static long time = 1000*5; private static String signature = "admin"; //創(chuàng)建token的方法 public static String createToken(){ JwtBuilder jwtBuilder = Jwts.builder(); String jwtToken = jwtBuilder //header .setHeaderParam("typ","JWT") .setHeaderParam("alg","HS256") //payload .claim("username","tom") .claim("role","admin") .setSubject("admin-test") .setExpiration(new Date(System.currentTimeMillis()+time)) .setId(UUID.randomUUID().toString()) //signature .signWith(SignatureAlgorithm.HS256,signature) .compact(); return jwtToken; } //校驗(yàn)token,布爾類(lèi)型 public static boolean checkToken(String token){ if (token ==null){ return false; } try { Jws<Claims> claimsJws = Jwts.parser().setSigningKey(signature).parseClaimsJws(token); }catch (Exception e){ return false; } return true; } }
創(chuàng)建控制器UserController
@RestController public class UserController { private final String USERNAME = "admin"; private final String PASSWORD = "123123"; //login方法 @GetMapping("/login") public User login(User user){ if(USERNAME.equals(user.getUsername()) && PASSWORD.equals(user.getPassword())){ //添加token user.setToken(JwtToken.createToken()); return user; } return null; } //校驗(yàn)token @GetMapping("/checkToken") //接收前端請(qǐng)求過(guò)來(lái)的header中的token,然后去jwtoken校驗(yàn)方法里校驗(yàn)這個(gè)token public Boolean checkToken(HttpServletRequest request){ String token = request.getHeader("token"); return JwtToken.checkToken(token); } }
不要忘了前后端分離中的跨域問(wèn)題, 我們?cè)诤蠖诉M(jìn)行跨域問(wèn)題的解決。
@Configuration public class CrosConfiguration implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOriginPatterns("*") .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") .allowCredentials(true) .maxAge(3600) .allowedHeaders("*"); } }
前端創(chuàng)建Vue項(xiàng)目
Login頁(yè)面:
<script> export default { name: "Login", data(){ return{ ruleForm: { username: 'admin', password: '123123' }, rules: { username: [{required: true, message: '請(qǐng)輸入用戶(hù)名', trigger: 'blur'}], password: [{required: true, message: '請(qǐng)輸入密碼', trigger: 'blur'}] } } }, methods: { handleSubmit(){ this.$refs.ruleForm.validate((valid) => { if(valid){ let _this = this axios.get('http://localhost:8080/login',{params:_this.ruleForm}).then(function (response) { if(response.data!=null){ //將token信息保存在本地客戶(hù)端 localStorage.setItem('access-admin',JSON.stringify(response.data)) _this.$router.replace({path:'/'}) } }) }else{ console.log('error submit!'); return false; } }) } } }; </script>
home頁(yè)面
export default { data(){ return { admin: '' } }, created() { //admin的信息從保存在客戶(hù)端中的信息中獲取 this.admin = JSON.parse(window.localStorage.getItem('access-admin')) } } </script>
index.js路由
router.beforeEach((to, from, next) => { if (to.path.startsWith('/login')) { //取出token信息 window.localStorage.removeItem('access-admin') next() } else { //獲取token的信息。 let admin = JSON.parse(window.localStorage.getItem('access-admin')) if (!admin) { next({path: '/login'}) } else { //校驗(yàn)token合法性 axios({ url:'http://localhost:8080/checkToken', method:'get', headers:{ token:admin.token } }).then((response) => { console.log(response.data) if(!response.data){ console.log('校驗(yàn)失敗') next({path: '/error'}) } }) next() } } }
到此這篇關(guān)于SpringBoot+Vue+JWT的前后端分離登錄認(rèn)證的文章就介紹到這了,更多相關(guān)SpringBoot登錄認(rèn)證內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java GUI實(shí)現(xiàn)加法計(jì)算器
這篇文章主要為大家詳細(xì)介紹了java GUI實(shí)現(xiàn)加法計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04spring?boot?validation參數(shù)校驗(yàn)與分組嵌套各種類(lèi)型及使用小結(jié)
參數(shù)校驗(yàn)基本上是controller必做的事情,畢竟前端傳過(guò)來(lái)的一切都不可信,validation可以簡(jiǎn)化這一操作,這篇文章主要介紹了spring?boot?validation參數(shù)校驗(yàn)分組嵌套各種類(lèi)型及使用小結(jié),需要的朋友可以參考下2023-09-09Java?DelayQueue實(shí)現(xiàn)延時(shí)任務(wù)的示例詳解
DelayQueue是一個(gè)無(wú)界的BlockingQueue的實(shí)現(xiàn)類(lèi),用于放置實(shí)現(xiàn)了Delayed接口的對(duì)象,其中的對(duì)象只能在其到期時(shí)才能從隊(duì)列中取走。本文就來(lái)利用DelayQueue實(shí)現(xiàn)延時(shí)任務(wù),感興趣的可以了解一下2022-08-08分析JVM源碼之Thread.interrupt系統(tǒng)級(jí)別線(xiàn)程打斷
在java編程中,我們經(jīng)常會(huì)調(diào)用Thread.sleep()方法使得線(xiàn)程停止運(yùn)行一段時(shí)間,而Thread類(lèi)中也提供了interrupt方法供我們?nèi)ブ鲃?dòng)打斷一個(gè)線(xiàn)程。那么線(xiàn)程掛起和打斷的本質(zhì)究竟是什么,本文就此問(wèn)題作一個(gè)探究2021-06-06Java超詳細(xì)講解接口的實(shí)現(xiàn)與用法
Java接口是一系列方法的聲明,是一些方法特征的集合,一個(gè)接口只有方法的特征沒(méi)有方法的實(shí)現(xiàn),因此這些方法可以在不同的地方被不同的類(lèi)實(shí)現(xiàn),而這些實(shí)現(xiàn)可以具有不同的行為2022-04-04java算法題解Leetcode15三數(shù)之和實(shí)例
這篇文章主要為大家介紹了java算法題解Leetcode15三數(shù)之和實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01解決spring AOP中自身方法調(diào)用無(wú)法應(yīng)用代理的問(wèn)題
這篇文章主要介紹了解決spring AOP中自身方法調(diào)用無(wú)法應(yīng)用代理的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Spring AOP 自定義注解的實(shí)現(xiàn)代碼
本篇文章主要介紹了Spring AOP 自定義注解的實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-04-04