JWT(JSON Web Token)简单使用

环境

jdk1.8+springboot+maven

使用场景

授权登录校验

引入依赖

        <!--java web token-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.8.3</version>
        </dependency>

编写工具类

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;

public class JwtUtils {

    /**
     * 创建token
     * @param userId
     * @return
     */
    public static String createToken(String userId,String nickName){
        if(nickName == null){
            nickName = "";
        }
        return JWT.create().withAudience(userId)//签发对象
                .withIssuedAt(new Date())
                .withClaim("nickName",nickName)//负载值
                .withClaim("userId",userId)
                .sign(Algorithm.HMAC256(userId+"myAppCheck"));//使用HMAC算法,userId+myAppCheck 作为密钥加密

    }

    /**
     * 校验
     * @param token
     * @param secret
     */
    public static boolean verifyToken(String token,String secret){
        DecodedJWT jwt = null;
        try{
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secret+"myAppCheck")).build();
            jwt = verifier.verify(token);
            return true;
        }catch (Exception e){
            return false;
        }
    }

    /**
     * 获取签发对象
     * @param token
     * @return
     */
    public static String getAudience(String token){
        String audience = null;
        try{
            audience = JWT.decode(token).getAudience().get(0);
        }catch (Exception e){
            //token解析失败
        }
        return audience;
    }

    /**
     * 获取负载值
     * @param token
     * @param name
     * @return
     */
    public static Claim getClaimByName(String token,String name){
        return JWT.decode(token).getClaim(name);
    }

}

使用

用户在进行登录时,生成token并返回,之后访问的请求中携带改token

String token = JwtUtils.createToken(userVo.getUserId(),userVo.getNickName());

创建一个注解,用于跳过登录验证(若不想使用注解,也可以在拦截器中配置不拦截的路径)


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PassToken {
    boolean required() default true;
}

编写拦截器



import com.myapp.tool.annotation.PassToken;
import com.myapp.tool.baseTool.JwtUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 路径拦截,权限判断
 */
public class JwtInterceptorAuth implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");//获取token,这里token我放在header上,所以在header获取
        if(!(handler instanceof HandlerMethod)){
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod)handler;
        Method method = handlerMethod.getMethod();
        //判断是否需要登录验证(是否有PassToken注解)
        if(method.isAnnotationPresent(PassToken.class)){
            PassToken passToken = method.getAnnotation(PassToken.class);
            if(passToken.required()){
                return true;
            }
        }else{
            System.out.println("拦截认证!");
            if(token == null){
                System.out.println("需要登录!");
                notTokenReturn(response);
                return false;
            }

            String userId = JwtUtils.getAudience(token);
            if(!JwtUtils.verifyToken(token,userId)){
                notTokenReturn(response);
                return false;
            }else{
                //可以获取负载中的值
                String userName = JwtUtils.getClaimByName(token,"userName").asString();
                request.setAttribute("userName",userName);
                return true;
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }





    private void notTokenReturn(HttpServletResponse response) throws Exception{
        response.setStatus(200);
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write("没登录");//这里返回的数据自己定义
        response.getWriter().flush();
    }



}

配置一下拦截器拦截所有路径请求


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 拦截器配置
 */
@Configuration
public class JwtInterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptorAuth())
                .addPathPatterns("/**");
    }

    @Bean
    public JwtInterceptorAuth jwtInterceptorAuth(){
        return new JwtInterceptorAuth();
    }


    /**
     * 设置返回格式
     * @param configurer
     */
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.defaultContentType(MediaType.APPLICATION_JSON);
    }
    

}

控制层(拿用户登录做个例子)

/**
     * 用户登录
     * @param u
     * @return
     */
    @PassToken
    @GetMapping(value = "/login")
    public String login(User u){
        //判断用户是否存在
        UserVo userVo = userService.selectUserByLogin(u.getLoginName(),u.getPassWord());
        if(userVo == null){
            throw new CustomException(ReturnCode.MC999,"用户名或密码错误");
        }
        //生成token并返回
        String token = JwtUtils.createToken(userVo.getUserId(),userVo.getNickName());
        Map reMap = new HashMap();
        reMap.put("user",userVo);
        reMap.put("token",token);
        if(StringUtils.isNotBlank(u.getcId()) ){
            userService.updateCid(userVo.getUserId(),u.getcId());
        }
        return ReturnData.reJson(reMap);
    }

水平有限,仅供参考。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值