前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【三】springboot整合token

【三】springboot整合token

作者头像
小z666
发布2024-06-21 17:56:25
960
发布2024-06-21 17:56:25
举报
文章被收录于专栏:javajava

介绍:接下来我会把学习阶段学到的框架等知识点进行整合,每一次整合是在前一章的基础上进行的,所以后面的整合不会重复放前面的代码。每次的demo我放在结尾,本次是接着上一章的内容延续的,只增加新增的或者修改的代码。

整合token,每次请求接口时进行token效验,效验通过才可以请求到接口,我是通过jwt生成的token。token个人理解大概就是用来判断用户登录状态,是否已登录的。

首先展示一下目录结构,是根据前面几章进行的增加(原因:内容过多),如下:

第一步:新增依赖(在pom文件增加)

代码语言:javascript
复制
<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--swagger        -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--swagger-ui.html模式        -->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.2</version>
        </dependency>
        <!--doc.html模式        -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>swagger-bootstrap-ui</artifactId>
            <version>1.9.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.auth0/java-jwt -->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.9.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.json/json -->
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20190722</version>
        </dependency>
    </dependencies>

其实就增加了jwt和json两个依赖。

第二步:新增配置类

代码语言:javascript
复制
TokenInterceptor类(拦截器):
代码语言:javascript
复制
@Component
public class TokenInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        //跨域请求会首先发一个option请求,直接返回正常状态并通过拦截器
        if(request.getMethod().equals("OPTIONS")){
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }
        response.setCharacterEncoding("utf-8");
        String token = request.getHeader("token");
        if (token!=null){
            boolean result= TokenUtils.verify(token);
            if (result){
                System.out.println("通过拦截器");
                return true;
            }
        }
        response.setContentType("application/json; charset=utf-8");
        try {
            JSONObject json=new JSONObject();
            json.put("msg","token verify fail");
            json.put("code","500");
            response.getWriter().append(json.toString());
            System.out.println("认证失败,未通过拦截器");
        } catch (Exception e) {
            return false;
        }
        /**
         * 还可以在此处检验用户存不存在等操作
         */
        return false;
    }
}

PS:此处token从request里面获取header里面的key值是token,你要根据自己的情况来,你在前端header里面传的token叫什么名称,这里就取什么名字。

代码语言:javascript
复制
WebConfiguration类(配置拦截器):
代码语言:javascript
复制
@Configuration
public class WebConfiguration implements WebMvcConfigurer {

    @Autowired
    private TokenInterceptor tokenInterceptor;

    /**
     * 解决跨域请求
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedHeaders("*")
                .allowedMethods("*")
//                .allowedOrigins("*")
                .allowedOriginPatterns("*")
                .allowCredentials(true);
    }

    /**
     * 异步请求配置
     * @param configurer
     */
    @Override
    public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
        configurer.setTaskExecutor(new ConcurrentTaskExecutor(Executors.newFixedThreadPool(3)));
        configurer.setDefaultTimeout(30000);
    }

    /**
     * 配置拦截器、拦截路径
     * 每次请求到拦截的路径,就会去执行拦截器中的方法
     * @param configurer
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        List<String> excludePath = new ArrayList<>();
        //排除拦截,除了注册登录(此时还没token),其他都拦截
        excludePath.add("/userController/login");  //登录
        excludePath.add("/userController/register");     //注册
        excludePath.add("/doc.html");     //swagger
        excludePath.add("/swagger-ui.html");     //swagger
        excludePath.add("/swagger-resources/**");     //swagger
        excludePath.add("/v2/api-docs");     //swagger
        excludePath.add("/webjars/**");     //swagger
//        excludePath.add("/static/**");  //静态资源
//        excludePath.add("/assets/**");  //静态资源
        registry.addInterceptor(tokenInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(excludePath);
        WebMvcConfigurer.super.addInterceptors(registry);

    }
}

PS:addInterceptors方法里面需要按自己情况进行修改,excludePath集合add的是需要放行的接口路径,前几章整合了swagger,所以此处需要放行swagger相关的路径,swagger-ui.html、doc.html、swagger-resources、等等,你再加上自己想要放行的接口路径即可,一般是首页请求的接口以及登录注册的接口(不需要进行token效验的接口)。

第三步:新增token工具类(用来生成token以及效验token)

代码语言:javascript
复制
public class TokenUtils {

    //token到期时间10小时
    private static final long EXPIRE_TIME= 10*60*60*1000;
    //密钥盐
    private static final String TOKEN_SECRET="ljdyaishijin**3nkjnj??";

    /**
     * 生成token
     * @param user
     * @return
     */
    public static String sign(User user){

        String token=null;
        try {
            Date expireAt=new Date(System.currentTimeMillis()+EXPIRE_TIME);
            token = JWT.create()
                    //发行人
                    .withIssuer("auth0")
                    //存放数据
                    .withClaim("username",user.getUserName())
                    //过期时间
                    .withExpiresAt(expireAt)
                    .sign(Algorithm.HMAC256(TOKEN_SECRET));
        } catch (IllegalArgumentException|JWTCreationException je) {

        }
        return token;
    }


    /**
     * token验证
     * @param token
     * @return
     */
    public static Boolean verify(String token){

        try {
            //创建token验证器
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
            DecodedJWT decodedJWT=jwtVerifier.verify(token);
            System.out.println("认证通过:");
            System.out.println("username: " + decodedJWT.getClaim("username").asString());
            System.out.println("过期时间:      " + decodedJWT.getExpiresAt());
        } catch (IllegalArgumentException |JWTVerificationException e) {
            //抛出错误即为验证不通过
            return false;
        }
        return true;
    }

}

PS:此处到期时间可以自定义按情况进行设置,1000是1秒。此处token的生成方法以及效验方法可以根据具体情况进行更改,生成token1是使用的jwt,此处验证方法存在一个用户有多个token的情况(可以同时多次登陆同一账号,重新请求token之后,前一次的token只要没有过期也能使用。),可以整合redis后进行改造(后面会讲到),可以达到一个用户只有一个token的效果(重新请求token之后,前一次的token即使没有过期也不能使用。)

第四步:改造登陆接口

代码语言:javascript
复制
@ApiOperation(value = "登录")
    @GetMapping("/login")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userName", value = "用户名", paramType = "String"),
            @ApiImplicitParam(name = "passWord", value = "密码", paramType = "String")
    })
    public BaseResponse<HashMap> login(@RequestParam(value = "userName") String userName, @RequestParam(value = "passWord") String passWord) throws JsonProcessingException {
        //包装token
        User user = new User();
        user.setUserName(userName);
        user.setPassword(passWord);
        String token= TokenUtils.sign(user);
        HashMap<String,Object> hs=new HashMap<>();
        hs.put("token",token);
        return RespGenerator.returnOK(hs);
    }

PS:可以根据自己的情况包装数据作为登录请求的返回结果。

第五步:演示结果

1、当请求没有放行的接口不带token请求时:

结果:会提示token效验失败。

2、当请求放行的接口不带token请求时:

结果:成功请求到接口,此处是登陆接口,返回了token。

3、当请求没有放行的接口带token请求时:

结果:成功请求到接口。

本期整合到此完毕,接下来会继续更新加强整合,尽情期待。

访问地址:http://localhost:8085/swagger-ui.html或者http://localhost:8085/doc.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-03-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一步:新增依赖(在pom文件增加)
  • 第二步:新增配置类
  • 第三步:新增token工具类(用来生成token以及效验token)
  • 第四步:改造登陆接口
  • 第五步:演示结果
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档