java restful token_java基于token验证之登陆验证(示例代码)

本文介绍了在Java RESTful应用中如何利用Token进行登录验证。通过JWT库生成和验证Token,确保前后端分离项目的安全性。文章提供了一个Token工具类的详细代码示例,包括Token的生成、验证以及在拦截器中的应用。前端使用Vue.js,通过axios库发送请求,并将接收到的Token存储在localStorage中,以便后续请求携带。
摘要由CSDN通过智能技术生成

转自博客 https://blog.csdn.net/weixin_39102174/article/details/90411116

以上博主讲的更清除些,此博客是为了自己加深记忆。

对于前后端分离的项目来说session来判断是否登陆实现比较困难,token是比较好的方式。

大概流程:

1.用户登陆,若成功则后台生成一个token,并把此token返回给客户端浏览器

2.客户端接收到token后,每次请求都要把此token放到header中发给后段

3.后段使用拦截器判断token的正确性和实效性。

以下是具体代码:

Token工具类:

package com.sign;

import com.auth0.jwt.JWT;

import com.auth0.jwt.JWTVerifier;

import com.auth0.jwt.algorithms.Algorithm;

import com.auth0.jwt.exceptions.JWTDecodeException;

import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;

import java.util.HashMap;

import java.util.Map;

public class TokenSign {

/**

* 过期时间60分钟

*/

private static final long EXPIRE_TIME=60 * 60 *1000;

/**

* 私钥,使用它生成token,最好进行下加密

*/

private static final String TOKEN_SECRET="Token";

/**

* 产生token

* @param useName

* @param userId

* @return

*/

public static String sign(String useName,String userId){

try{

//设置15分钟失效

Date date=new Date(System.currentTimeMillis()+EXPIRE_TIME);

//私钥及加密算法

Algorithm algorithm=Algorithm.HMAC256(TOKEN_SECRET);

//设置头部信息

Map header=new HashMap<>();

header.put("typ","JWT");

header.put("alg","HS256");

//附带username和userid信息,存储到token中,生成签名

return JWT.create()

.withHeader(header)

//存储自己想要留存给客户端浏览器的内容

.withClaim("userName",useName)

.withClaim("userId",userId)

.withExpiresAt(date)

.sign(algorithm);

}catch (Exception e){

e.printStackTrace();

}

return null;

}

/**

* token校验是否正确

* @param token

* @return

*/

public static boolean verify(String token){

try {

Algorithm algorithm=Algorithm.HMAC256(TOKEN_SECRET);

JWTVerifier verifier =JWT.require(algorithm).build();

//此方法若token验证失败会抛错的,所以直接return true没问题

DecodedJWT decodedJWT =verifier.verify(token);

return true;

}catch (Exception e){

e.printStackTrace();

}

return false;

}

/**

* 获取token中信息 userName

* @param token

* @return

*/

public static String getUsername(String token) {

try {

DecodedJWT jwt = JWT.decode(token);

return jwt.getClaim("userName").asString();

} catch (JWTDecodeException e) {

e.getStackTrace();

}

return null;

}

/**

* 获取token中信息 userId

* @param token

* @return

*/

public static String getUserId(String token) {

try {

DecodedJWT jwt = JWT.decode(token);

return jwt.getClaim("userId").asString();

} catch (JWTDecodeException e) {

e.getStackTrace();

}

return null;

}

}

拦截器:

package com.interceptor;

import com.alibaba.fastjson.JSONObject;

import com.constant.TokenConstant;

import com.sign.TokenSign;

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.util.HashMap;

import java.util.Map;

@Component

public class LoginInterceptor implements HandlerInterceptor {

// 在请求处理之前调用,只有返回true才会执行要执行的请求

@Override

public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {

httpServletResponse.setCharacterEncoding("UTF-8");

String token=httpServletRequest.getHeader("accessToken");

if (null==token){

Map map=new HashMap<>();

map.put("data","token is null");

map.put("code","401");

httpServletResponse.getWriter().write(JSONObject.toJSONString(map));

return false;

}else {

boolean result= TokenSign.verify(token);

if (result){

//更新存储的token信息

TokenConstant.updateTokenMap(token);

return true;

}

Map map=new HashMap<>();

map.put("data","token is null");

map.put("code","401");

httpServletResponse.getWriter().write(JSONObject.toJSONString(map));

return false;

}

}

// 试图渲染之后执行

@Override

public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

}

// 在请求处理之后,视图渲染之前执行

@Override

public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

}

}package com.constant;

import java.util.HashMap;

import java.util.Map;

public class TokenConstant {

private static Map map=new HashMap();

public static String getToken(){

return map.get("token");

}

public static void updateTokenMap(String token){

map.put("token",token);

}

}

注册拦截器:

package com.adapter;

import com.interceptor.LoginInterceptor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.servlet.config.annotation.CorsRegistry;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration

public class LoginAdapter implements WebMvcConfigurer {

//解决跨域问题

@Override

public void addCorsMappings(CorsRegistry registry) {

registry.addMapping("/**")

.allowedHeaders("Content-Type","X-Requested-With","accept,Origin","Access-Control-Request-Method","Access-Control-Request-Headers","token")

.allowedMethods("*")

.allowedOrigins("*")

//是否允许使用cookie

.allowCredentials(true);

}

@Autowired

private LoginInterceptor loginInterceptor;

// 这个方法是用来配置静态资源的,比如html,js,css,等等

@Override

public void addResourceHandlers(ResourceHandlerRegistry registry) {

}

// 这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效

@Override

public void addInterceptors(InterceptorRegistry registry) {

System.out.println("进入拦截器");

//addPathPatterns是表明拦截哪些请求

//excludePathPatterns是对哪些请求不做拦截

registry.addInterceptor(loginInterceptor).addPathPatterns("/**").excludePathPatterns("/user/login");

}

}

以上是后台的配置,除了登陆所有请求都会进行token验证。

前端代码概要:

前端用的VUE

import Vue from ‘vue‘;

import Axios from ‘axios‘

import { Toast } from ‘we-vue‘

export default {

name: ‘Login‘,

data: function () {

return {

user: {account: ‘‘, password: ‘‘},

show: false,

url:this.GLOBAL.loginUrl,

isDisable:false,

loadingShow:false

}

},

methods: {

ok: function () {

if (!this.user.account || !this.user.password) {

// Toast.loading(‘加载中‘);

Toast.text(‘请完善登陆信息‘);

console.log(‘param not allow null‘)

return

};

this.isDisable=true;

this.loadingShow=true;

setTimeout(() => {

Axios.post(this.url,

this.user,

{ //方式2通过transformRequest方法发送数据,本质还是将数据拼接成字符串

transformRequest:[

function(data){

let params=‘‘;

for(let index in data){

params+=index+‘=‘+data[index]+‘&‘;

}

return params;

}

]

})

.then(response => {

if (response.data) {

//存储token

localStorage.setItem(‘accessToken‘, response.data);

this.$router.push({ path: ‘home‘ })

}else {

Toast.fail(‘登陆失败‘);

console.log(‘登陆失败:‘, response.data.message)

}

this.loadingShow=false;

this.isDisable=false;

})

.catch(error => {

Toast.fail(‘请求失败‘);

console.log(‘请求失败:‘, error)

this.loadingShow=false;

this.isDisable=false;

})

}, 1000)

},

cancel: function () {

this.show = false

this.$emit(‘cancel‘, this.flowParam)

}

}

}

登陆界面最主要的是:localStorage.setItem(‘accessToken‘, response.data);把token信息存储

每次请求都放到header中:

此处简写:

Axios.post(this.addUrl,param,

{headers: {‘Content-Type‘:‘application/json;charset=UTF-8‘,‘accessToken‘:localStorage.getItem(‘accessToken‘)}},

{method: ‘put‘}

).then(response => {

localStorage.getItem(‘accessToken‘);获取存储在localStorage中的token信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值