當(dāng)前位置:首頁(yè) > IT技術(shù) > 編程語(yǔ)言 > 正文

springboot + vue實(shí)現(xiàn)token登錄攔截器
2021-11-01 14:29:43

一.后端

?

后端目錄:

?

?

?

1.pom依賴需引入jwt

<dependency>
? <groupId>io.jsonwebtoken</groupId>
? <artifactId>jjwt</artifactId>
? <version>0.9.0</version>
</dependency>

2.token工具類,用來生成token以及校驗(yàn)token

public class TokenUtil {
? public static void main(String[] args) {
? ? ? User u = new User("admin","123");
? ? ? System.out.println(sign(u));
? }
? private static final long EXPIRE_TIME = 10*60*60*1000;
? private static final String PRIVATE_KEY = "abcde"; //密鑰
?
? /**
? ? * 簽名生成
? ? * @param user
? ? * @return
? ? */
? public static String sign(User user){
? ? ? String token = null;
? ? ? Map<String,Object> header = new HashMap<>();
? ? ? header.put("typ","JWT");
? ? ? header.put("alg","HS256");
? ? ? Map<String,Object> claims = new HashMap<>();
? ? ? //自定義有效載荷部分
? ? ? claims.put("account",user.getUserId());
? ? ? token = Jwts.builder()
? ? ? ? ? ? ? //發(fā)證人
? ? ? ? ? ? ? .setIssuer("auth")
? ? ? ? ? ? ? //Jwt頭
? ? ? ? ? ? ? .setHeader(header)
? ? ? ? ? ? ? //有效載荷
? ? ? ? ? ? ? .setClaims(claims)
? ? ? ? ? ? ? //設(shè)定簽發(fā)時(shí)間
? ? ? ? ? ? ? .setIssuedAt(new Date())
? ? ? ? ? ? ? //設(shè)定過期時(shí)間
? ? ? ? ? ? ? .setExpiration(new Date(System.currentTimeMillis() + EXPIRE_TIME))
? ? ? ? ? ? ? //使用HS256算法簽名,PRIVATE_KEY為簽名密鑰
? ? ? ? ? ? ? .signWith(SignatureAlgorithm.HS256,PRIVATE_KEY)
? ? ? ? ? ? ? .compact();
? ? ? return token;
? }
?
? /**
? ? * 驗(yàn)證 token信息 是否正確
? ? * @param token 被解析 JWT
? ? * @return 是否正確
? ? */
? public static boolean verify(String token){
? ? ? //獲取簽名密鑰
? ? ? //String key = userEntity.getUserPassword();
? ? ? //獲取DefaultJwtParser
? ? ? try{
? ? ? ? ? Jwts.parser()
? ? ? ? ? ? ? ? ? //設(shè)置 密鑰
? ? ? ? ? ? ? ? ? .setSigningKey(PRIVATE_KEY)
? ? ? ? ? ? ? ? ? //設(shè)置需要解析的 token
? ? ? ? ? ? ? ? ? .parseClaimsJws(token).getBody();
? ? ? ? ? return true;
? ? ? }catch (Exception e){
? ? ? ? ? return false;
? ? ? }
? }
}

3.TokenInterceptor 攔截器

@Component
public class TokenInterceptor extends HandlerInterceptorAdapter {
?
? // 重寫 前置攔截方法
? @Override
? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
? ? ? ? ? throws Exception {
? ? ? if (HttpMethod.OPTIONS.toString().equals(request.getMethod())) {
? ? ? ? ? System.out.println("OPTIONS請(qǐng)求,放行");
? ? ? ? ? return true;
? ? ? }
? ? ? // 1、從請(qǐng)求頭中獲取token
? ? ? String token = request.getHeader("token");
? ? ? System.out.println(token);
? ? ? // 2、判斷 token 是否存在
? ? ? if (token == null || "".equals(token)) {
? ? ? ? ? System.out.println("未登錄");
? ? ? ? ? return false;
? ? ? }
?
? ? ? // 3、解析token
? ? ? if(!TokenUtil.verify(token)){
? ? ? ? ? return false;
? ? ? }
?
? ? ? return true;
? }
}

4.WebMvcConfig 注冊(cè)攔截器

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
?
? // 注入 token 攔截器
? @Autowired
? private TokenInterceptor interceptor;
?
? /**
? ? * 重寫添加攔截器
? ? */
? @Override
? public void addInterceptors(InterceptorRegistry registry) {
? ? ? // 添加自定義攔截器,并攔截對(duì)應(yīng) url"
? ? ? registry.addInterceptor(interceptor).addPathPatterns("/**").excludePathPatterns("/login");
? }
}

5.User實(shí)體類

public class User {
? private String userId;
? private String password;
?
? public User(String id,String word){
? ? ? this.userId = id;
? ? ? this.password = word;
? }
? public String getUserId() {
? ? ? return userId;
? }
?
? public void setUserId(String userId) {
? ? ? this.userId = userId;
? }
?
? public String getPassword() {
? ? ? return password;
? }
?
? public void setPassword(String password) {
? ? ? this.password = password;
? }
}

6.controller接口

@CrossOrigin
@RestController
public class UserController{
? @RequestMapping(value = "/login",method = RequestMethod.POST)
? @ResponseBody
? public String login(@RequestBody Map<String,String> para) throws JsonProcessingException {
? ? ? String username=para.get("username");
? ? ? String password=para.get("password");
? ? ? String token= TokenUtil.sign(new User(username,password));
? ? ? HashMap<String,Object> hs=new HashMap<>();
? ? ? hs.put("token",token);
? ? ? ObjectMapper objectMapper=new ObjectMapper();
? ? ? return objectMapper.writeValueAsString(hs);
? }
?
? @RequestMapping(value = "/demo",method = RequestMethod.POST)
? public String hello(){
? ? ? System.out.println("sdhfkhsdf");
? ? ? return "Nihao ";
? } ?
}

二.前端

前端目錄:one.vue頁(yè)面是多余的 不用管

?

?

?

1.登錄頁(yè)面

<template>

<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="auto" class="demo-ruleForm" >

<el-form-item label-width="300px" >

</el-form-item>

<el-form-item label="賬號(hào):" label-width="50px" prop="pass">

<el-input clearable name="name" type="username" v-model.trim="ruleForm.pass" autocomplete="off" placeholder="請(qǐng)輸入賬號(hào)" style="width: 250px"></el-input>

</el-form-item>

<el-form-item label="密碼:" label-width="50px" prop="checkPass">

<el-input clearable name="word" type="password" v-model.trim="ruleForm.checkPass" autocomplete="off" placeholder="請(qǐng)輸入密碼" style="width: 250px"></el-input>

</el-form-item>

<el-form-item label-width="95px">

<el-button type="primary" @click="handleSubmit">登錄</el-button>

</el-form-item>

</el-form>

</div>

</template>

?

<script>

export default {

data () {

var validatePass = (rule, value, callback) => {

if (value === '') {

callback(new Error('請(qǐng)輸入賬號(hào)'))

}

}

var validatePass2 = (rule, value, callback) => {

if (value === '') {

callback(new Error('請(qǐng)輸入密碼'))

}

}

return {

ruleForm: {

pass: '',

checkPass: ''

},

userToken: '',

userid: '',

userword: '',

rules: {

pass: [

{ validator: validatePass, trigger: 'blur' }

],

checkPass: [

{ validator: validatePass2, trigger: 'blur' }

]

}

}

},

methods: {

handleSubmit () {

let params = {

'username': this.ruleForm.pass,

'password': this.ruleForm.checkPass

}

?

this.$axios.post('http://localhost:8080/login', params).then(res => {

// 請(qǐng)求成功

?

console.log(res.data)

this.userToken = res.data.token

// 將用戶token保存

alert(this.userToken)

localStorage.setItem('token', this.userToken)

?

this.$router.push('/main')

}).catch(() => {

// 請(qǐng)求失敗,

this.$Message.error('登錄失?。≌?qǐng)檢查登錄信息是否正確!')

})

}

}

}

</script>

<style type="text/css">

.login{

position: absolute;/絕對(duì)定位/

width: 300px;

height: 200px;

text-align: center;/(讓div中的內(nèi)容居中)/

top: 50%;

left: 50%;

margin-top: -200px;

margin-left: -150px;

}

</style>

2.登錄成功后的main頁(yè)面(為了測(cè)試,就只寫了一個(gè)按鈕,登錄成功后,跳轉(zhuǎn)到這個(gè)頁(yè)面,再點(diǎn)擊按鈕返回一條后端信息)

<template>

<el-button type="primary" @click="mount">登錄</el-button>

</div>

</template>

<script>

export default {

methods: {

mount () {

alert(localStorage.getItem('token'))

this.$axios.post('http://localhost:8080/demo').then(res => {

// 請(qǐng)求成功

alert(res.data)

}).catch(() => {

// 請(qǐng)求失敗,

alert(222)

})

}

}

}

</script>

3.main.js中加入全局配置請(qǐng)求頭代碼

import Vue from 'vue'

import App from './App'

import router from './router'

import ElementUI from 'element-ui'

import axios from 'axios'

import 'element-ui/lib/theme-chalk/index.css'

import Vuex from 'vuex'

?

Vue.use(Vuex)

Vue.use(ElementUI)

Vue.prototype.$axios = axios

Vue.config.productionTip = false

?

/* eslint-disable no-new */

new Vue({

el: '#app',

router,

components: { App },

template: '<App/>'

})

axios.interceptors.request.use(function (config) {

// 為請(qǐng)求頭添加Authorization字段為服務(wù)端返回的token

config.headers.token = localStorage.getItem('token')

// return config是固定用法 必須有返回值

return config

})

三.測(cè)試

前端頁(yè)面路由:(one這個(gè)是多余的不用管,到時(shí)候直接輸入8081/login頁(yè)面就行)

?

?

?

打開url:http://localhost:8081/#/login

?

?

隨便輸入賬號(hào)和密碼就行,為了測(cè)試,后端沒有去從數(shù)據(jù)庫(kù)拿數(shù)據(jù),登錄后跳轉(zhuǎn)到main頁(yè)面

?

?

點(diǎn)擊登錄按鈕:

?

?

?

?

?

成功!

?

本文摘自 :https://www.cnblogs.com/

開通會(huì)員,享受整站包年服務(wù)立即開通 >