zoukankan      html  css  js  c++  java
  • springboot结合jwt实现基于restful接口的身份认证

    基于restful接口的身份认证,可以采用jwt的方式实现,想了解jwt,可以查询相关资料,这里不做介绍~

    下面直接看如何实现

    1、首先添加jwt的jar包,pom.xml中添加依赖包:

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

    2、添加工具类JwtUtil.java:

    package com.demo.news.common;
    
    import io.jsonwebtoken.Jwts;
    import io.jsonwebtoken.SignatureAlgorithm;
    
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    
    public class JwtUtil {
        static final String SECRET = "ThisIsASecret";
    
        public static String generateToken(String username) {
            HashMap<String, Object> map = new HashMap<>();
            //you can put any data in the map
            map.put("username", username);
            String jwt = Jwts.builder()
                    .setClaims(map)
                    .setExpiration(new Date(System.currentTimeMillis() + 3600_000_000L))// 1000 hour
                    .signWith(SignatureAlgorithm.HS512, SECRET)
                    .compact();
            return "Bearer "+jwt; //jwt前面一般都会加Bearer
        }
    
        public static void validateToken(String token) {
            try {
                // parse the token.
                Map<String, Object> body = Jwts.parser()
                        .setSigningKey(SECRET)
                        .parseClaimsJws(token.replace("Bearer ",""))
                        .getBody();
            }catch (Exception e){
                throw new IllegalStateException("Invalid Token. "+e.getMessage());
            }
        }
    }

    这个工具类有两个方法,一个生成token,一个验证token

    添加过滤器JwtAuthenticationFilter.java

    package com.demo.news.common;
    
    import org.springframework.util.AntPathMatcher;
    import org.springframework.util.PathMatcher;
    import org.springframework.web.filter.OncePerRequestFilter;
    
    import javax.servlet.FilterChain;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    
    public class JwtAuthenticationFilter extends OncePerRequestFilter {
        private static final PathMatcher pathMatcher = new AntPathMatcher();
    
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            try {
                if(isProtectedUrl(request)) {
                    String token = request.getParameter("token");
                    //检查jwt令牌, 如果令牌不合法或者过期, 里面会直接抛出异常, 下面的catch部分会直接返回
                    JwtUtil.validateToken(token);
                }
            } catch (Exception e) {
                response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
                return;
            }
            //如果jwt令牌通过了检测, 那么就把request传递给后面的RESTful api
            filterChain.doFilter(request, response);
        }
    
    
        //我们只对地址 /api 开头的api检查jwt. 不然的话登录/login也需要jwt
        private boolean isProtectedUrl(HttpServletRequest request) {
            return pathMatcher.match("/api/**", request.getServletPath());
        }
    
    }

    这个过滤器会过滤所有以api打头的路径

    注册过滤器MyJwtFilter.java

    package com.demo.news.common;
    
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyJwtFilter {
        
        @Bean
        public FilterRegistrationBean jwtFilter() {
            final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
            JwtAuthenticationFilter filter = new JwtAuthenticationFilter();
            registrationBean.setFilter(filter);
            return registrationBean;
        }
    
    }

    3、开始使用

    通过之前的代码,所有路径以api开头的请求如果不添加token参数都会报没有权限的错误,说明过滤器已经生效了

    下面我们根据用户名和密码来验证用户身份,如果用户身份通过验证,那个生成token,拿到这个token,路径以api打头的请求添加上这个token参数

    验证用户身份的代码:

    if(用户验证成功) {
        String token = JwtUtil.generateToken(user.getUsername());
    }

    拿到这个token,在路径以api打头的请求上添加上这个token,比如:

    http://localhost:8083/news/api/list?token=Bearer eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE1NTM2MjQxMzgsInVzZXJuYW1lIjoiYWRtaW4ifQ.FQsNIr_b9105CoV-jx8k9lgtyJ6cM_z48g1fQeSUBowkOGBk-OXGdgtVa1215lD75U3N3tF3yZs10MtJ7kZstA

  • 相关阅读:
    zookeeper C API
    《accelerated c++》第九章---设计类
    redis memcache 比较
    redis 学习记录
    php memcache 使用学习
    php新手需要注意的高效率编程
    linux常用命令
    curl和file_get_contents 区别以及各自的优劣
    php序列化问题
    socket编程 123
  • 原文地址:https://www.cnblogs.com/modou/p/10368837.html
Copyright © 2011-2022 走看看