使用 JWT 实现 token 认证

使用 JWT 实现 token 认证

1. 导包

<dependency>
	<groupId>io.jsonwebtoken</groupId>
	<artifactId>jjwt</artifactId>
	<version>0.9.1</version>
</dependency>

2. 工具类

package com.springCloud.common.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;

@ConfigurationProperties(prefix = "jwt.config")
@Component
@Data
public class JWT {

    private String key;

    private long expiration;

    /**
     * 创建 JWT
     * @param id 用户的 id 号
     * @param subject 用户名
     * @param role 用户的角色
     * @return JWT 编码.
     */
    public String createJWT(String id, String subject, String role) {
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        JwtBuilder jwtBuilder = Jwts.builder()
                .setId(id)
                .setSubject(subject)
                .setIssuedAt(now)
                .signWith(SignatureAlgorithm.HS256, key)
                .claim("role", role);
        if (expiration > 0) {
            jwtBuilder.setExpiration(new Date(nowMillis + expiration));
        }
        return jwtBuilder.compact();
    }

    /**
     * 解析 JWT
     * @param jwtString JWT 编码字符串
     * @return String
     */
    public Claims parseJWT(String jwtString) {
        return Jwts.parser()
                .setSigningKey(key)
                .parseClaimsJws(jwtString)
                .getBody();
    }

}

3. 拦截器

package com.springCloud.user.interceptor;

import com.springCloud.common.util.JWT;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class JwtInterceptor implements HandlerInterceptor {

    private JWT jwt;

    @Autowired
    private JwtInterceptor(JWT jwt) {
        this.jwt = jwt;
    }


    /**
     * 如论如何都需要放行, 而拦截需要在操作中去判断.
     * login 中 拦截器只需要将请求头中包括 token 的令牌进行解析.
     *
     * @param request  请求
     * @param response 响应
     * @param handler  处理
     * @return boolean
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        // 得到请求头中的 Authorization.
        String header = request.getHeader("Authorization");
        // 判断是否进行拦截
        if (header != null && !"".equals(header) && header.startsWith("Bearer ")) {
            // 得到 token
            String token = header.substring(7);
            // 进行对 token 解析.
            try {
                Claims claims = jwt.parseJWT(token);
                // 得到登录的角色
                String role = (String) claims.get("role");
                if ("admin".equals(role)) {
                    request.setAttribute("token_admin", token);
                    request.setAttribute("claims_admin", claims);
                }
                if ("user".equals(role)) {
                    request.setAttribute("token_user", token);
                    request.setAttribute("claims_user", claims);
                }
            } catch (Exception e) {
                throw new RuntimeException("令牌不正确");
            }

        }
        return true;
    }

}

package com.springCloud.user.config.interceptor;

import com.springCloud.user.interceptor.JwtInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    private JwtInterceptor jwtInterceptor;

    /**
     * 这里需要是 public 修饰
     *
     * @param jwtInterceptor jwtInterceptor
     */
    @Autowired
    public InterceptorConfig(JwtInterceptor jwtInterceptor) {
        this.jwtInterceptor = jwtInterceptor;
    }

    /**
     * Registered Interceptor
     *
     * @param registry registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 注册拦截器要声明拦截器对象和拦截器请求.
        registry.addInterceptor(jwtInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/**/login**/**");
    }

}

4. 配置

加上下面的文件防止警告

> **这里是引用**

{
  "properties": [
    {
      "name": "jwt.config.key",
      "type": "java.lang.String",
      "description": "Description for jwt.config.key.",
      "defaultValue": "springCloud"
    },
    {
      "name": "jwt.config.expiration",
      "type": "java.lang.Long",
      "description": "Description for jwt.config.expiration.",
      "defaultValue": 3600000
    }
  ]
}


在配置文件中

jwt:
  config:
    expiration: 3600000
    key: key

5. 使用

添加


    private UserService userService;
    private RedisTemplate<String, String> redisTemplate;
    private HttpServletRequest request;
    private JWT jwt;

    /**
     * 获取容器对象
     *
     * @param userService 识别 userService 容器对象
     */
    @Autowired
    private UserController(UserService userService,
                           RedisTemplate<String, String> redisTemplate,
                           HttpServletRequest request,
                           JWT jwt) {
        this.userService = userService;
        this.redisTemplate = redisTemplate;
        this.request = request;
        this.jwt = jwt;
    }


    /**
     * 登录用户时需要前后端通话的操作 JWT
     *
     * @param user 用户
     * @return Result
     */
    private Result login_jwt(User user) {
        String token = this.jwt.createJWT(user.getId(), user.getName(), "user");
        Map<String, Object> map = new HashMap<>();
        map.put("id", user.getId());
        map.put("role", "user");
        map.put("token", token);
        return new Result(StatusCode.OK, true, "用户登录成功", map);
    }


    /**
     * 手机号登录
     *
     * @param user 用户
     * @return Result
     */
    @PostMapping("/login_phone")
    public Result login_phone(@RequestBody User user) {
        User login = userService.login_phone(user);
        if (login == null) {
            return new Result(StatusCode.LOGIN_ERROR, false, "用户登录失败");
        }
        // 登录成功了, 需要进行前后端通话的操作. JWT
        return login_jwt(login);
    }

    /**
     * 自动登录
     *
     * @return Result
     */
    @PostMapping("/authLogin")
    public Result login() {
        Claims token_user = (Claims) request.getAttribute("claims_user");
        String id = token_user.getId();
        String role = (String) token_user.get("role");
        if (role == null || "".equals(role)) {
            return new Result(StatusCode.LOGIN_ERROR, false, "登录失效");
        }
        // 登录成功了, 需要进行前后端通话的操作. JWT
        return new Result(StatusCode.OK, true, "自动登录成功", userService.findById(id));
    }

猜你喜欢

转载自blog.csdn.net/YKenan/article/details/106319534