加载中...

Java开发中token 的使用


Java开发中token 的使用

Token

流程: 1.建立token工具类,先编辑token签名sign():设置超时时长、token秘钥。 2.配置拦截器类,拦截器中重写preHandle()方法,对每次请求进行自定义的拦截操作。 3.建立配置类:定义拦截与不拦截的接口信息。

页面请求登录接口→登录成功后,返回登录信息+token秘钥给前端→前端记住密钥信息,并赋予每个接口(例:在每个接口访问时将秘钥信息放置于headers中的参数下)→拦截器接到请求,从headers获取token密钥进行匹配,通过则继续访问,不通过则返回提示信息。

1.建立token工具类,先编辑token签名sign():设置超时时长、token秘钥。

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import lombok.extern.slf4j.Slf4j;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JwtUtil {
  /**
     * 过期时间
     */
  private static final long EXPIRE_TIME = 15 * 60 * 1000;
  /**
      * token秘钥
      */
  private static final String TOKEN_SECRET = "c369a1e4-43ee-4e1e-b130-2b952f1ba9ad";
  /**
 * 签名方法
 * @Param userName  userName
 * @Param role  role
 * @return String role
 */
  public static String sign(String userName, String role) {
    log.info("sign begin.");
    try {
      // 过期时间
      Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
      // 秘钥和加密算法
      Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
      // headers
      Map<String, Object> herders = new HashMap<>(2);
      herders.put("typ", "JWT");
      herders.put("alg", "HS256");
      log.info("sign end.");
      return JWT.create()
        .withHeader(herders)
        .withClaim("userName", userName)
        .withClaim("role", role)
        .withExpiresAt(date)
        .sign(algorithm);
    } catch (UnsupportedEncodingException exception) {
      exception.printStackTrace();
      log.info("sign error.");
      return exception.getMessage();
    }
  }

  /**
 * token 校验方法
 * @Param userName  userName
 * @return String role
 */
  public static boolean verify(String token) {
    log.info("verify begin.");
    try {
      Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
      JWTVerifier verifier = JWT.require(algorithm).build();
      verifier.verify(token);
      log.info("verify end.");
      return true;
    } catch (UnsupportedEncodingException exception) {
      log.info("verify error.");
      exception.printStackTrace();
      return false;
    }
  }
}

2.controller层登录操作中设置登录校验及token插入:

/**
 * @program: smartOperationTest
 * @description: 用户操作
 * @author: 作者名字
 * @create: 2021-07-15 10:37
 **/
@Controller
@RequestMapping("/user")
@Api("userActionController")
@CrossOrigin(value = "*", maxAge = 3600)
@Slf4j
public class UserActionController {

  @Autowired
  UserInfoServiceImpl userInfoService;

  @RequestMapping(value = "/login", method = RequestMethod.GET)
  @ApiOperation(value = "登录", notes = "")
  @ResponseBody
  public CommonResultBO userLogin(@RequestParam() String username, @RequestParam() String password) {
    CommonResultBO resultBO = userInfoService.getUserInfo(username, password);
    Integer statusCode = resultBO.getStatusCode();
    if (statusCode == 200) {// 登录校验通过则插入token信息
      UserInfo userInfo = (UserInfo)resultBO.getData();
      String token = JwtUtil.sign(username, userInfo.getRole());
      resultBO.setData(token);
      return resultBO;
    }
    resultBO.setData("");
    resultBO.setStatusCode(1);
    resultBO.setStatusMessage("token failed");
    return resultBO;
  }
}

3.设置拦截器

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @program: smartOperationTest
 * @description: 拦截器
 * @author: 作者名字
 * @create: 2021-07-15 16:20
 **/
@Component
@Slf4j
public class TokenInterceptor implements HandlerInterceptor {

  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws IOException {
    log.info("preHandle begin.");
    response.setCharacterEncoding("utf-8");
    String token = request.getHeader("accessToken");
    log.info("preHandle begin TOKEN: {}." + token);
    // token通过验证 返回true 继续访问
    if (null != token) {
      boolean result = JwtUtil.verify(token) ;
      if (result) {
        log.info("preHandle end.");
        return true;
      }
    }
    // token验证不通过 返回失败提示
    CommonResultBO commonResultBO = CommonResultBO.init(null, -1, "failed", "token invalid");
    response.getWriter().write(JSONObject.toJSONString(commonResultBO));
    log.info("preHandle end.");
    return false;
  }
}

4.建立配置类,明确拦截与不拦截的接口:/*拦截一层路径,/**拦截/后全布路径。

import com.hawk.smartoperationtest.common.TokenInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.*;

/**
 * @program: smartOperationTest
 * @description: 自定义拦截器配置
 * @author: 作者名字
 * @create: 2021-07-15 16:48
 **/
@Configuration
@Slf4j
public class MvcConfig extends WebMvcConfigurationSupport {

  @Autowired
  TokenInterceptor tokenInterceptor;

  @Override
  protected void addInterceptors(InterceptorRegistry registry) {
    //添加自定义拦截器
    log.info("addInterceptors begin.");
    InterceptorRegistration patterns = registry.addInterceptor(tokenInterceptor).addPathPatterns("/mary/**")    //指定拦截的url地址
      .excludePathPatterns("/user/**", "/swagger-resources/**", "/v2/**");
    log.info("addInterceptors :" + patterns.toString());
  }

  /**
    * 发现如果继承了WebMvcConfigurationSupport,则在yml中配置的相关内容会失效。
    * 配置拦截器后swagger访问会被拦截 按如下配置可保持swagger访问
    * 需要重新指定静态资源
    * @param registry
    */
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    //registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
    registry.addResourceHandler("swagger-ui.html")
      .addResourceLocations("classpath:/META-INF/resources/");
    registry.addResourceHandler("/webjars/**")
      .addResourceLocations("classpath:/META-INF/resources/webjars/");
    //super.addResourceHandlers(registry);
  }
}

登录验证通过后,再次进行接口访问时,header中就要携带token信息进行校验。例:

accessToken:xxxtoken加密信息xxxx

verify()也可以用于任意地方进行token校验。

解析token:例

DecodedJWT verify = verifier.verify(token);
String role = verify.getClaim("role").asString();

文章作者: 解你忧
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 解你忧 !
  目录