Springboot中配置Token

王淞*

java,springboot,token,拦截,令牌

项目描述

用户第一次登陆时,服务端会生成一个 Token,再把这个 Token 发送给用户端,用户端每次向服务端请求资源的时候,都必须携带 这个token,服务端直接解密token就可以知道用户的相关信息,避免每次都需要核验用户信息,省去查询数据库的操作. 减轻数据库压力。

上传时间

2023.02.20

浏览人数

284人
王淞*
辽宁省沈阳市沈河区
Hot:563

一.通过在pom文件中添加JWT依赖,调用token功能


<dependency>

    <groupId>com.auth0</groupId>

    <artifactId>java-jwt</artifactId>

    <version>3.4.0</version>

</dependency>


二.在config文件夹下创建TokenConfig文件

Springboot中配置Token

三.在TokenConfig文件中定义两个注释,通过这两个注释来使用token功能


public class TokenConfig {

    //定义跳过token验证的注解

    @Target({ElementType.METHOD, ElementType.TYPE})

    @Retention(RetentionPolicy.RUNTIME)

    public @interface PassToken{

        boolean required() default true;

    }

    //定义需要Token验证的注解

    @Target({ElementType.METHOD, ElementType.TYPE})

    @Retention(RetentionPolicy.RUNTIME)

    public @interface UserLoginToken{

        boolean required() default true;

    }

}


四.创建三层架构(controller-service-dao),和pojo后续测试token时使用

Springboot中配置Token1.pojo文件内的操作,可以下载lombok插件简化代码,先在pom添加lombok依赖


<dependency>

   <groupId>org.projectlombok</groupId>

   <artifactId>lombok</artifactId>

   <version>1.16.20</version>

   <scope>provided</scope>

</dependency>


2.下载lombok插件,idea左上角File-->Settings

Springboot中配置Token


3.在pojo文件头部加上这三个注释


@Data

@AllArgsConstructor

@NoArgsConstructor

以代替

Springboot中配置Token

@Data

@AllArgsConstructor

@NoArgsConstructor

public class AdminsPojo {

    private Long id;

    private String phone;

    private String password;

    private String token;

}



@Data

@AllArgsConstructor

@NoArgsConstructor

public class BookPojo {

    private Long id;

    private String bookname;

    private String author;

    private String publisher;

}



@Data

@AllArgsConstructor

@NoArgsConstructor

public class JsonMsgPojo {

    private int status;

    private String msg;

    private Object data;

}


五.创建utils文件夹,在内部创建TokenTools文件来生成token密文(封装函数)

Springboot中配置Token

public class TokenTools {

    //生成token密文的函数

    public static String getToken(AdminsPojo ap) {

        Date start = new Date();//开始生效时间

        long currentTime = System.currentTimeMillis() +  60*60*60 * 1000;//60小时有效时间(根据项目要求)

        Date end = new Date(currentTime); //失效时间

        //在这里使用了用户的id和密码以生成一个token

        String token = JWT.create().withAudience(ap.getPhone().toString()).withIssuedAt(start).withExpiresAt(end)

                .sign(Algorithm.HMAC256(ap.getPassword()));

        return token;

    }

}


六.创建拦截器函数(在访问功能函数前会判断是否有token注解,有则验证,没有就跳过)

Springboot中配置Token

public class AuthenticationInterceptor implements HandlerInterceptor {

    @Autowired

    private AdminService adminService;

    @Override

    //prehandle函数会在Controller里的函数被调用之前提前调用

    //所以在这里可以达到提前拦截的效果

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 从 http 请求头中取出 token

        String token = request.getHeader("token");

        // 如果不是映射到方法直接通过

        if (!(handler instanceof HandlerMethod)) {

            return true;

        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;

        Method method = handlerMethod.getMethod();//获取到被注解的函数

        //检查函数是否有@PassToken注解,有则直接跳过认证

        if (method.isAnnotationPresent(TokenConfig.PassToken.class)) {

            TokenConfig.PassToken passToken = method.getAnnotation(TokenConfig.PassToken.class);

            if (passToken.required()) {

                return true;

            }

        }

        //检查函数是否有UserLoginToken注解, 有则执行验证, 无则执行return true

        if (method.isAnnotationPresent(TokenConfig.UserLoginToken.class)) {

            TokenConfig.UserLoginToken userLoginToken = method.getAnnotation(TokenConfig.UserLoginToken.class);

            if (userLoginToken.required()) {

                // 执行认证

                if (token == null) {

                    throw new RuntimeException("当前无token信息,请重新登录!");

                }

                // 获取token中的phone----------phone为自定义的字段,作为登录账号使用

                String phone;

                try {

                    phone = JWT.decode(token).getAudience().get(0);

                } catch (JWTDecodeException j) {

                    throw new RuntimeException("Token获取失败或有误!");

                }

                //通过token中的phone来验证是否存在----------phone为自定义的字段,作为登录账号使用

                AdminsPojo ap = new AdminsPojo();

                ap.setPhone(phone);

                AdminsPojo adp = adminService.findAdminsById(ap);

                if (adp == null) {

                    throw new RuntimeException("当前用户ID不存在,请重新登录!");

                }

                // 通过token中的password与最新查询到password对比 来验证token的正确性----------password为自定义的字段,作为登录账号使用

                JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(adp.getPassword())).build();

                try {

                    jwtVerifier.verify(token);

                } catch (JWTVerificationException e) {

                    throw new RuntimeException("Token获取失败或已过期!");

                }

                return true;

            }

        }

        return true;

    }

    @Override

    public void postHandle(HttpServletRequest request,

                           HttpServletResponse response,

                           Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override

    public void afterCompletion(HttpServletRequest request,

                                HttpServletResponse response,

                                Object o, Exception e) throws Exception {

    }

}


七.添加拦截器函数的配置文件(设定拦截的访问路径范围)

Springboot中配置Token

@Configuration

public class InterceptorConfig implements WebMvcConfigurer {

    @Override

    public void addInterceptors(InterceptorRegistry registry) {

        registry.addInterceptor(authenticationInterceptor())

                .addPathPatterns("/**");

        //这里的 /** 代表的是拦截所有的访问路径

    }

    @Bean

    public AuthenticationInterceptor authenticationInterceptor() {

        return new AuthenticationInterceptor();

    }

}


八.测试token功能

1.在登录函数中加入跳过token验证的注释


@PostMapping("login")

    @ResponseBody

    @TokenConfig.PassToken

    public JsonMsgPojo login(AdminsPojo ap) {

        AdminsPojo adp = adminService.login(ap);

        if (adp == null) {

            return new JsonMsgPojo(500, "用户名或密码错误!", null);

        }

        String token = TokenTools.getToken(ap);

        ap.setToken(token);

        return new JsonMsgPojo(200, "登陆成功!", ap);

    }


2.返回的结果中会携带token

Springboot中配置Token



3.复制token的数据,下一个功能测试时需要用到(每次登录生成的token数据都不同)

4.全查询函数,需要附加token验证


@GetMapping("getbooks")

    @ResponseBody

    @TokenConfig.UserLoginToken

    public JsonMsgPojo getbooks() {

        List<BookPojo> bp = adminService.getbooks();

        if (bp == null) {

            return new JsonMsgPojo(500, "不存在!", null);

        }

        return new JsonMsgPojo(200, "查询成功!", bp);

    }


5.在headers中加入token字段和相应数据

Springboot中配置Token

Springboot中配置Token


6.若是没在Headers中加入token字段

Springboot中配置Token

王淞*

5分

很棒的作品 希望在下一个版本加上token并有权限的验证
Django 天津Java培训 天津Java培训班 天津Java培训哪家好?天津Java培训机构 java python ajax 天津Java培训 天津Java培训班 天津Java培训班管用吗 天津Java培训班哪家好 Java 天津Java培训 Java培训 天津编程培训 Java Java培训班 Eclipse Tomcat Git 天津Java培训 Java培训 天津编程培训 Java Java培训班 Eclipse MyEclipse IntelliJ IDEA 天津Java培训 Java培训班 Java开发 Java 天津Java开发培训 Eclipse MyEclipse 天津Java培训 天津Java开发培训 天津Java培训班 Eclipse MyEclipse 天津Java培训 天津Java开发培训 天津Java培训班 Java开发培训 C/C++ Java Python 天津Java培训 天津Java开发培训 天津Java培训班 Java开发培训 C/C++ Java Python 天津Java培训 天津Java开发培训 天津Java培训班 Java开发培训 C/C++ Java Python 天津Java培训 天津Java开发培训 天津Java培训班 Java开发培训 C/C++ Java Python 天津Java培训 天津Java开发培训 天津Java培训班 Java开发培训 C/C++ Java Python 天津Java培训 天津Java开发培训 天津Java培训班 Java开发培训 Java python web前端 天津Java培训 天津Java 培训班 天津Java培训机构 天津Java开发培训 Editplus ltraEdit Eclipse 天津Java培训 天津Java培训班 Java开发培训 Java培训机构 ps ai 天津Java培训 天津Java培训班 天津Java培训机构 Java培训 Java开发培训 java python web 天津Java培训 天津Java培训机构 天津Java培训班 天津Java培训学校 java python web 天津Java培训 天津Java培训机构 天津Java培训学校 天津Java培训哪家好 Java python web 天津Java培训 天津Java培训学校 Java python web 天津Java培训 天津Java 开发培训 天津Java开发培训机构 java python web 天津Java培训 天津Java培训机构 Java培训班 天津Java培训学校 Java python web 天津Java培训 天津Java培训班 天津Java培训机构 Java培训 Java python web 天津Java培训 天津Java培训机构 天津Java培训班 Java培训 java web python 天津Java培训 天津Java培训班 天津Java培训学校 Java培训机构 Java培训 java python web 天津Java培训 天津Java培训机构 Java培训 天津Java培训学校 java python web 天津Java培训 天津Java培训班 天津Java培训机构 Java培训学校 java python web 天津Java培训 天津Java培训班 天津Java培训学校 Java培训 java python web 天津Java培训 天津Java配训学校 Java培训 java web python 天津Java培训 天津Java培训班 Java培训机构 Java培训 Java python web 天津Java培训 天津Java培训班 天津Java培训机构 Java培训 java python web 天津Java培训 天津Java培训班 天津Java培训机构 java python web 天津Java培训 天津Java培训班 天津Java培训机构 Java web python 天津Java培训 天津Java培训学校 Java培训 java web python 天津Java培训 天津Java培训机构 Java培训 java web python 天津Java培训 天津Java培训机构 Java培训 java web python 天津Java培训 天津Java培训机构 Java培训 java web python 天津Java培训 天津Java培训班 Java培训 java web python 天津Java培训 天津Java培训班 Java培训机构 java python web 天津Java培训 天津Java培训哪家好
王淞*    563 辽宁省沈阳市沈河区 设计师杨冰是女孩 1998.**.**
本网站已在中国版权保护中心登记了美术作品著作权与软件著作权违者将依法追究责任,特此声明! | Copyright©2013-2022,zhuzuoji.com | 诚筑说培训学校(天津)有限公司内容支持 | 京ICP备17020986号-5