Java如何实现登录token令牌

2022-07-14,,,,

一、流程图

二、token

1、token是一种客户端认证机制,是一个经过加密的字符串,安全性强,支持跨域

2、用户第一次登录,服务器通过数据库校验其userid和password合法,则再根据随机数字+userid+当前时间戳再经过des加密生成一个token串

  • 当然具体生成token的方式是开发自己定义的   

3、token的生成一般是采用uuid保证唯一性,当用户登录时为其生成唯一的token,存储一般保存在数据库中

  • token过期时间采用把token二次保存在cookie或session里面,根据cookie和session的过期时间去维护token的过期时间

4、token是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回token给前端。前端可以在每次请求的时候带上token证明自己的合法地位

5、token,就是令牌,最大的特点就是随机性,不可预测。一般黑客或软件无法猜测出来

三、分析

建立一个token令牌,在用户登录时候给用户一个独特得令牌值,登录时候嘚赋值这个令牌

在springboot项目中建立一个util文件夹

文件夹下建立tokenutil.java文件

public class tokenutil {  
    private static map<string, user> tokenmap = new hashmap<>();  
    public static string generatetoken(user user){
        //生成唯一不重复的字符串
        string token = uuid.randomuuid().tostring();
        tokenmap.put(token,user);
        return token;
    }
 
    /**
     * 验证token是否合法
     * @param token
     * @return
     */
    public static  boolean verify(string token){
        return tokenmap.containskey(token);
    }
 
    public static user gentuser(string token){
        return tokenmap.get(token);
    }
 
    public static void main(string[] args) {
        for (int i = 0; i < 20; i++){
            system.out.println(uuid.randomuuid().tostring());
        }
    } 
}

用户登录得usercontroller.java

@api( tags = {"用户模块接口"})
@restcontroller
@requestmapping("user")
public class usercontroller {
    @autowired
    private userservice userservice;
 
    @autowired
    private httpsession session;
    @apioperation("登录接口")
    @requestmapping(value = "login",method ={requestmethod.post,requestmethod.get})
    public map<string,object> login(user user){
        map<string,object> map = new hashmap<>();
        map.put("code",0);
        if(stringutils.isempty(user.getusername()) || stringutils.isempty(user.getpassword()) ){
            map.put("msg","用户或者密码为空!");
            return map;
        }
        querywrapper<user> querywrapper = new querywrapper<>();
        querywrapper.eq("username",user.getusername())
                .eq("password",user.getpassword());
        user userdb = userservice.getone(querywrapper);
        if(userdb != null){
            string token= tokenutil.generatetoken(userdb);
            map.put("code",1);
            map.put("data",userdb);
            map.put("token",token);
            session.setattribute("username",userdb.getusername());
        }else{
            map.put("msg","用户名或密码错误!");
        }
        return map;
    }
    @apiimplicitparams(
            {
            @apiimplicitparam(name = "id",
                    value = "用户id", required = true,
                    datatype = "long"),
            @apiimplicitparam(name = "name",
                    value = "测试名字",
                    datatype = "string")
            }
    )
    @apioperation("根据id查询用户信息")
    @requestmapping(value="getbyid",method ={requestmethod.post,requestmethod.get})
    public  user getbyid(long id ,string name){
        system.out.println(name);
        return userservice.getbyid(id);
    }
 
}

在拦截器上操作 interceptor下面logininterceptor.java

public class logininterceptor implements handlerinterceptor {
 
    @autowired
    private httpsession httpsession;
 
    //controller逻辑执行之前
    @override
    public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception {
        system.out.println("prehandle....");
        string uri = request.getrequesturi();
        system.out.println("当前路径:"+uri);
        /**
         * handlermethod=>controller中标注@requestmapping的方法
         *  需要配置静态资源不拦截时,添加这块逻辑  => 前后端分离项目
         *
         */
        // 是我们的conrtoller中的方法
        if (!(handler instanceof handlermethod)) {
            return true;
        }
        string token = request.getheader("qcby-token");
        if (!tokenutil.verify(token)) {
            // 未登录跳转到登录界面
           throw  new runtimeexception("no login!");
        } else {
            return true;
        }
    }
 
    //controller逻辑执行完毕但是视图解析器还未进行解析之前
    @override
    public void posthandle(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, modelandview modelandview) throws exception {
        system.out.println("posthandle....");
    }
 
    //controller逻辑和视图解析器执行完毕
    @override
    public void aftercompletion(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, exception e) throws exception {
        system.out.println("aftercompletion....");
    }
}

四、运行结果

http://localhost:8080/

 http://localhost:8080/user/login?username=admin&password=123456

 记住这个令牌    

60227b0e-bdbb-47d9-9df4-f56163cb529d

在postman中

写入令牌,输出成功

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

《Java如何实现登录token令牌.doc》

下载本文的Word格式文档,以方便收藏与打印。