SpringBoot+Vue下的token

一.后端(Spingboot)
1.定义注解
SpringBoot+Vue下的token_第1张图片
2.定义TokenService类

@Service
public class TokenService {
    //生成token
    public String getToken(User user){
        String token = "";
        token = JWT.create().withAudience(user.getUserName()).sign(Algorithm.HMAC256(user.getUserPassword()));
        return token;
    }
}

3.编写拦截器

public class AuthenticationInterceptor implements HandlerInterceptor {
    @Autowired
    UserMapper userMapper;


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");//获取token
        //不为映射到方法直接通过
        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;
            }
        }
        //检测是否有需要用户权限的注解
        if(method.isAnnotationPresent(UserLoginToken.class)){
            UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);

            if(userLoginToken.required()){
                //执行认证
                if(token == null){
                    throw new RuntimeException("401");
                }
                //获取token中的username
                String userName;
                try{
                    userName = JWT.decode(token).getAudience().get(0);
                }catch (JWTDecodeException j){
                    throw new RuntimeException("401");
                }
                User user = userMapper.selectUserByName(userName);
                if(user == null){
                    throw new RuntimeException("401");
                }
                //验证token
                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getUserPassword())).build();
                try{
                    jwtVerifier.verify(token);
                }catch (JWTVerificationException e){
                    throw new RuntimeException("401");
                }
                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 {

    }
}

4.配置拦截器

@Configuration
public class MyPicConfig implements WebMvcConfigurer {
	@Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor();
    }
    
    //拦截所有请求,判断是否有@LoginRequired注解决定是否需要登录
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authenticationInterceptor()).addPathPatterns("/**");
    }
    
}

5.使用
(1)不加@UserLoginToken注解默认通过

	@PostMapping("/login")
    public Object login(@RequestBody User user){
        JSONObject jsonObject = new JSONObject();
        User userForBase = userMapper.selectUserByName(user.getUserName());
        if(userForBase == null){
            jsonObject.put("message","登录失败,用户不存在");
            return jsonObject;
        }else{
            if(!userForBase.getUserPassword().equals(user.getUserPassword())){
                jsonObject.put("message","登录失败,密码错误");
                return jsonObject;
            }
            else{
                if(userForBase.getUserGrade() == 0){
                    jsonObject.put("message","您的信用分数过低,已被网站拦截");
                    return jsonObject;
                }
                String token = tokenService.getToken(userForBase);
                jsonObject.put("token",token);
                jsonObject.put("user",userForBase);
                return jsonObject;
            }
        }
    }

(2)添加注解则需要进行token检测

	@UserLoginToken
    @GetMapping("/getMessage")
    public String getMessage(){
        return "你已通过验证";
    }

二.前端(vue)
1.配置vuex(store/index.js)

export default new Vuex.Store({
  state: {
      token: localStorage.getItem('token')?localStorage.getItem('token'):'',
  },
  mutations: {
    setToken(state,token){
      state.token = token;
      localStorage.setItem("token",token);
    },
    delToken(state){
      state.token = '';
      localStorage.removeItem('token');
    }
  },
  actions: {
  },
  modules: {
  }
})

2.添加拦截器(main.js)

axios.interceptors.request.use(config => {
    //判断是否存在token,如果存在将每个页面header都添加token
    if(store.state.token){
        config.headers.common['Authorization'] = store.state.token
    }
    return config;
}, error => {

});

// http response 拦截器
axios.interceptors.response.use(
    response => {
        return response;
    },
    error => {
        if (error.response) {
            switch (error.response.data.message) {//若message为404则返回登录页
                case '401':
                    store.commit('delToken');
                    router.replace('/login');
            }
        }
    });

3.使用

				login(){
                if(!(this.userName!=''&&this.password!='')){
                    this.$message("请输入账号与密码!");
                    return;
                }
                let url = 'http://localhost:8080/user/login'
                axios.post(url,{userName:this.userName,userPassword:this.password}).then(res=>{
                    if(res.data['message']){
                        this.$message(res.data['message']);
                        return;
                    }
                    let token = res.data['token'];//token
                    this.$store.commit('setToken',token);
                    //console.log(window.localStorage['token']);  可以直接获取token值
                    //console.log(this.$store.state.token);
                    window.localStorage.setItem("username",this.userName);
                    this.$router.push('/forum');
                }).catch(err=>{
                    console.log(err);
                })
            }

三.参考文章
1.SpringBoot集成JWT实现token验证
2.Vue项目中的token验证登录(前端部分)

你可能感兴趣的:(个人学习记录)