jwt鉴权登录实现步骤(JWT工具类+拦截器+前端配置)——前后端鉴权方案和使用

11 篇文章 2 订阅

一、大致思路:

1、第一次登录的时候,前端调后端的登陆接口,发送用户名和密码

2、后端收到请求,验证用户名和密码,验证成功,就给前端返回一个token

3、前端拿到token,将token存储到localStorage和vuex中,并跳转路由页面

4、前端每次跳转路由,就判断 localStroage 中有无 token ,没有就跳转到登录页面,有则跳转到对应路由页面

5、每次调后端接口,都要在请求头中加token

6、后端判断请求头中有无token,有token,就拿到token并验证token,验证成功就返回数据,验证失败(例如:token过期)就返回401,请求头中没有token也返回401

7、如果前端拿到状态码为-10000,就清除token信息并跳转到登录页面鉴权登陆

二、后端处理 

1.编写JWT类

package com.example.api_project.JWT;

import com.auth0.jwt.JWTSigner;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.internal.com.fasterxml.jackson.databind.ObjectMapper;

import java.util.HashMap;
import java.util.Map;

public class JWT {
    private static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545fdf>?N<:{LWPW";

    private static final String EXP = "exp";

    private static final String PAYLOAD = "payload";

    //加密,传入一个对象和有效期
    public static <T> String sign(T object, long maxAge) {
        try {
            final JWTSigner signer = new JWTSigner(SECRET);
            final Map<String, Object> claims = new HashMap<String, Object>();
            ObjectMapper mapper = new ObjectMapper();
            String jsonString = mapper.writeValueAsString(object);
            claims.put(PAYLOAD, jsonString);
            claims.put(EXP, System.currentTimeMillis() + maxAge);
            return signer.sign(claims);
        } catch(Exception e) {
            return null;
        }
    }

    //解密,传入一个加密后的token字符串和解密后的类型
    public static<T> T unsign(String jwt, Class<T> classT) {
        final JWTVerifier verifier = new JWTVerifier(SECRET);
        try {
            final Map<String,Object> claims= verifier.verify(jwt);
            if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
                long exp = (Long)claims.get(EXP);
                long currentTimeMillis = System.currentTimeMillis();
                if (exp > currentTimeMillis) {
                    String json = (String)claims.get(PAYLOAD);
                    ObjectMapper objectMapper = new ObjectMapper();
                    return objectMapper.readValue(json, classT);
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

}

2.编写拦截器

package com.example.api_project.JWT;

import java.io.PrintWriter;

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

import com.alibaba.fastjson.JSON;
import com.example.api_project.model.ResponseData;
import com.example.api_project.model.Result;
import com.example.api_project.pojo.User;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSONObject;

//自定义拦截器
public class TokenInterceptor implements HandlerInterceptor{
    /**
     * preHandle()返回true后,afterCompletion()才会执行
     */
    public void afterCompletion(HttpServletRequest request,HttpServletResponse response,
                                Object handler, Exception arg3) throws Exception {
    }

    /**
     * 该方法在调用controller方法后,DispatcherServlet渲染视图之前被执行
     */
    public void postHandle(HttpServletRequest request, HttpServletResponse response,
                           Object handler, ModelAndView model) throws Exception {
    }

    /**
     * 发起请求前调用
     * 该方法返回false的话,将不会往下执行
    */
    //拦截每个请求
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        response.setCharacterEncoding("utf-8");
        String token = request.getHeader("token");
        System.out.println("preHandle....." + token);
        Result responseData;

        //token存在
        if(null != token) {
            User login = JWT.unsign(token, User.class);//解码
            String userId = request.getHeader("userId");//获取userId

            if(null != userId && null != login) {
                //一致,返回true 正常执行
                if(userId.equals(login.getUserId())) {
                    return true;
                }
                //解密token后的userId与用户传来的userId不一致,一般都是token过期
                else{
                    responseData = ResponseData.authError();
                    responseMessage(response, response.getWriter(), responseData);
                    return false;
                }
            }
            //有一个或者多个为空
            else
            {
                responseData = ResponseData.authError();
                responseMessage(response, response.getWriter(), responseData);
                return false;
            }
        }
        //token不存在
        else
        {
            responseData = ResponseData.authError();
            responseMessage(response, response.getWriter(), responseData);
            return false;
        }
    }

    //请求不通过,返回错误信息给客户端
    private void responseMessage(HttpServletResponse response, PrintWriter out, Result responseData) {
        response.setContentType("application/json; charset=utf-8");
        String json = JSONObject.toJSONString(responseData);
        out.print(json);
        out.flush();
        out.close();
    }

}

3.配置拦截器

package com.example.api_project.JWT;

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 WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //设置拦截路径,排除路径,优先级等
        registry.addInterceptor(new TokenInterceptor())
                .excludePathPatterns("/api/login/**").order(11)
                .addPathPatterns("/api/user/**");

    }
}

 4.在loginController中的使用

    //登录
    @RequestMapping("/login")
    @ResponseBody
    public Result login(User user) {
        User temp= userService.selectForLogin(user);
        if(temp!=null){
            User u = userService.findOneUser(user);
            //给用户jwt加密生成token【//创建JWT令牌】
            String token = JWT.sign(u, 60L* 1000L* 30L);
            //封装成对象返回给客户端
            Result responseData = new Result<>();
            responseData.putDataValue("userId", user.getUserId());
            responseData.putDataValue("token", token);
            responseData.putDataValue("user", u);
            responseData.Result();
            return responseData;
        }else{
            return ResponseData.error("账号或密码错误!");
        }
    }

 三、前端处理 

1.配置request

// 2.请求拦截器
service.interceptors.request.use(config => {
  config.data = JSON.stringify(config.data); 
  config.headers = {
    'Content-Type':'application/json' //配置请求头
  }
  const token = localStorage.getItem('token');
  const userId = localStorage.getItem('userId');
  if(token){
    // config.params = {'userId':userId} 
    config.headers.userId = userId 
    config.headers.token= token 
  }
  return config
}, error => {
  Promise.reject(error)
})

2.配置response

// 3.响应拦截器
service.interceptors.response.use(response => {
  var token = response.headers['token'];
  //有token
	if(token){
		window.vm.$store.commit('token',{token:token});
  }
  if (response.data.code == -10000) {
    localStorage.clear()
    router.push({ name: 'login' })
    Message({
      message: "鉴权登陆失败",
      type: "error",
    });
  } 
  return response
}, error => {})

这样就可以了啦!~好像也不难呢!~springboot项目不需要再写那么多乱七八糟的配置文件 ~~~

关于返回类型的统一封装,可以参考这篇笔记

Java后端返回结果统一封装http://t.csdn.cn/6Ba23

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是一个使用 Spring Boot、JWT拦截器实现登录验证的示例代码: 1. 添加 JWT 依赖 在 pom.xml 文件中添加以下依赖: ```xml <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-api</artifactId> <version>0.11.2</version> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-impl</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt-jackson</artifactId> <version>0.11.2</version> <scope>runtime</scope> </dependency> ``` 2. 创建 JWT 工具类 ```java import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; import org.springframework.stereotype.Component; import java.security.Key; import java.util.Date; import java.util.HashMap; import java.util.Map; @Component public class JwtUtil { private final Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256); public String generateToken(String subject) { return Jwts.builder() .setClaims(new HashMap<>()) .setSubject(subject) .setExpiration(new Date(System.currentTimeMillis() + 60 * 60 * 1000)) .signWith(key) .compact(); } public boolean validateToken(String token) { try { Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token); return true; } catch (Exception e) { return false; } } public String getUsernameFromToken(String token) { Claims claims = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody(); return claims.getSubject(); } } ``` 3. 创建拦截器 ```java import com.example.demo.jwt.JwtUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; 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; @Component public class AuthenticationInterceptor implements HandlerInterceptor { @Autowired private JwtUtil jwtUtil; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token = request.getHeader("Authorization"); if (token != null && jwtUtil.validateToken(token)) { String username = jwtUtil.getUsernameFromToken(token); request.setAttribute("username", username); return true; } else { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return false; } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); LoginRequired loginRequired = method.getAnnotation(LoginRequired.class); if (loginRequired != null && modelAndView != null) { modelAndView.addObject("username", request.getAttribute("username")); } } } ``` 4. 创建注解 ```java import java.lang.annotation.*; @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface LoginRequired { } ``` 5. 创建控制器 ```java import com.example.demo.interceptor.LoginRequired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @GetMapping("/") public String index() { return "Hello World"; } @GetMapping("/hello") @LoginRequired public String hello() { return "Hello " + SecurityContextHolder.getContext().getAuthentication().getName(); } } ``` 6. 配置拦截器 ```java import com.example.demo.interceptor.AuthenticationInterceptor; 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 WebMvcConfig implements WebMvcConfigurer { @Autowired private AuthenticationInterceptor authenticationInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authenticationInterceptor).addPathPatterns("/**"); } } ``` 7. 创建登录控制器 ```java import com.example.demo.jwt.JwtUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; @RestController public class LoginController { @Autowired private JwtUtil jwtUtil; @PostMapping("/login") public Map<String, Object> login(@RequestBody Map<String, String> params) { String username = params.get("username"); String password = params.get("password"); // TODO: 验证用户名和密码 String token = jwtUtil.generateToken(username); Map<String, Object> result = new HashMap<>(); result.put("token", token); return result; } } ``` 在这个示例中,我们创建了一个 JWT 工具类来生成和验证 JWT,创建了一个拦截器来验证用户是否登录,并使用 @LoginRequired 注解来标记需要登录验证的方法。我们还创建了一个登录控制器来生成 JWT。通过这个示例,您可以了解如何使用 Spring Boot、JWT拦截器实现登录验证。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值