JWTTOKEN前后端分离,springboot2结合JWTtoken

编程

1.JWT简介

        JSON Web Token(缩写 JWT),是目前最流行的跨域认证解决方案。

2.JWT的原理

       JWT的原理是,服务器认证以后,生成一个JSON格式的对象,发回给客户端,就像下面这样.

 

{

"用户名": "admin",

"角色": "超级管理员",

"到期时间": "2019-07-13 00:00:00"

}

 

          以后,客户端与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。

       为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名(详见后文)。

        服务器不再保存任何 session 数据,也就是服务器变成无状态了,从而比较容易实现扩展。

3.JWT的数据结构

        实际的 JWT是一个很长的字符串,中间用点(.)分隔成三个部分。 就像下面这样:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjNmMmc1N2E5MmFhIn0.eyJpYXQiOjE1NjI4MzM0MDgsImlzcyI6Imh0dHA6XC9cL3d3dy5weWcuY29tIiwiYXVkIjoiaHR0cDpcL1wvd3d3LnB5Zy5jb20iLCJuYmYiOjE1NjI4MzM0MDcsImV4cCI6MTU2MjkxOTgwOCwianRpIjoiM2YyZzU3YTkyYWEiLCJ1c2VyX2lkIjoxfQ.NFq1qQ-Z5c4pwit8ZkyWEwX6SBXmnHJcc6ZDgSD5nhU

          JWT的三个部分依次如下:

- Header(头部)

- Payload(负载)

- Signature(签名)

4.JWT的使用方式

             客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。

此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面

5.JWT的几个特点

          (1)JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。

           (2)JWT 不加密的情况下,不能将秘密数据写入 JWT。

           (3)JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。

           (4)JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

           (5)JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

           (6)为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。

6.JWT功能实现

import java.util.Calendar;

import java.util.Date;

import java.util.GregorianCalendar;

import java.util.HashMap;

import java.util.Map;

import com.auth0.jwt.JWT;

import com.auth0.jwt.JWTVerifier;

import com.auth0.jwt.algorithms.Algorithm;

import com.auth0.jwt.exceptions.JWTCreationException;

import com.auth0.jwt.exceptions.JWTVerificationException;

import com.auth0.jwt.interfaces.Claim;

import com.auth0.jwt.interfaces.DecodedJWT;

public class JwtHelper {

// 秘钥

static final String SECRET = "X-Token";

// 签名由谁生成

static final String ISSUSER = "WXW";

// 签名的主题

static final String SUBJECT = "this is my token";

// 签名的观众

static final String AUDIENCE = "MINAPP";

public String createToken(Integer userId){

try {

Algorithm algorithm = Algorithm.HMAC256(SECRET);

Map<String, Object> map = new HashMap<String, Object>();

Date nowDate = new Date();

// 过期时间:2小时

Date expireDate = getAfterDate(nowDate,0,0,0,2,0,0);

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

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

String token = JWT.create()

// 设置头部信息 Header

.withHeader(map)

// 设置 载荷 Payload

.withClaim("userId", userId)

.withIssuer(ISSUSER)

.withSubject(SUBJECT)

.withAudience(AUDIENCE)

// 生成签名的时间

.withIssuedAt(nowDate)

// 签名过期的时间

.withExpiresAt(expireDate)

// 签名 Signature

.sign(algorithm);

return token;

} catch (JWTCreationException exception){

exception.printStackTrace();

}

return null;

}

public Integer verifyTokenAndGetUserId(String token) {

try {

Algorithm algorithm = Algorithm.HMAC256(SECRET);

JWTVerifier verifier = JWT.require(algorithm)

.withIssuer(ISSUSER)

.build();

DecodedJWT jwt = verifier.verify(token);

Map<String, Claim> claims = jwt.getClaims();

Claim claim = claims.get("userId");

return claim.asInt();

} catch (JWTVerificationException exception){

// exception.printStackTrace();

}

return 0;

}

public Date getAfterDate(Date date, int year, int month, int day, int hour, int minute, int second){

if(date == null){

date = new Date();

}

Calendar cal = new GregorianCalendar();

cal.setTime(date);

if(year != 0){

cal.add(Calendar.YEAR, year);

}

if(month != 0){

cal.add(Calendar.MONTH, month);

}

if(day != 0){

cal.add(Calendar.DATE, day);

}

if(hour != 0){

cal.add(Calendar.HOUR_OF_DAY, hour);

}

if(minute != 0){

cal.add(Calendar.MINUTE, minute);

}

if(second != 0){

cal.add(Calendar.SECOND, second);

}

return cal.getTime();

}

}

 

import org.linlinjava.litemall.wx.util.JwtHelper;

/**

* token 管理

*/

public class UserTokenManager {

public static String generateToken(Integer id) {

JwtHelper jwtHelper = new JwtHelper();

return jwtHelper.createToken(id);

}

public static Integer getUserId(String token) {

if( null == token ){

return null;

}

JwtHelper jwtHelper = new JwtHelper();

Integer userId = jwtHelper.verifyTokenAndGetUserId(token);

if(userId == null || userId == 0){

return null;

}

return userId;

}

public static void main(String[] args) {

System.out.println(generateToken(9));

}

}

 

使用

自定义参数解析器 

过程:  根据请求, 解析请求头中的token,获得到用户信息,将用户信息传递对应请求的method。

可查看原文: https://blog.csdn.net/sunshine_YG/article/details/85125373 

 

1.自定义注解类

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)

@Retention(RetentionPolicy.RUNTIME)

public @interface LoginUser {

}

2.解析类

import com.xxx.xx.LoginUser;

import com.xxx.xx.UserTokenManager;

import org.springframework.core.MethodParameter;

import org.springframework.web.bind.support.WebDataBinderFactory;

import org.springframework.web.context.request.NativeWebRequest;

import org.springframework.web.method.support.HandlerMethodArgumentResolver;

import org.springframework.web.method.support.ModelAndViewContainer;

public class LoginUserHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {

public static final String LOGIN_TOKEN_KEY = "X-Token";

@Override

public boolean supportsParameter(MethodParameter parameter) {

return parameter.getParameterType().isAssignableFrom(Integer.class) && parameter.hasParameterAnnotation(LoginUser.class);

}

@Override

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer container,

NativeWebRequest request, WebDataBinderFactory factory) throws Exception {

// return new Integer(1);

String token = request.getHeader(LOGIN_TOKEN_KEY);

if (token == null || token.isEmpty()) {

return null;

}

return UserTokenManager.getUserId(token);

}

}

 

3.注册配置

import com.xxx.xx.xx.LoginUserHandlerMethodArgumentResolver;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.method.support.HandlerMethodArgumentResolver;

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

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

import java.util.List;

@Configuration

public class WxWebMvcConfiguration implements WebMvcConfigurer {

@Override

public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {

argumentResolvers.add(new LoginUserHandlerMethodArgumentResolver());

}

// 拦截器

public void addInterceptors(InterceptorRegistry registry) {

// 可设置拦截器

}

}

 

4. 使用

import com.xxx.xxx.xxx.ResponseUtil;

import com.xxx.xxx.xxx.LoginUser;

import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

/**

* index服务

*/

@RestController

@RequestMapping("/index")

public class IndexController {

@GetMapping("index")

public Object index(@LoginUser Integer userId) {

// 打印userId

return ResponseUtil.ok(userId);

}

}

 

5. postman请求i携带

 

获取完毕

 

 

 

以上是 JWTTOKEN前后端分离,springboot2结合JWTtoken 的全部内容, 来源链接: utcz.com/z/511478.html

回到顶部