设为首页 加入收藏

TOP

token验证(一)
2023-07-23 13:25:15 】 浏览:60
Tags:token 验证

token验证

什么是token?我相信很多开发者都或多或少听过基于 token 的用户鉴权和基于 session 的用户鉴权,而今天说的 token 验证就是第一种了。token 的意思是“令牌”,是用户第一次登录服务器返回的,它能让用户不需要提交账户和密码就能进行服务器验证身份,它是被放在请求头中一起提交给服务器的。

为什么用 token 验证?怎么用 token 验证?现在简单介绍一下,有错误请大牛指出,我会立即更正!

首先是为什么用?

  1. 为了验证用户的登录情况,毕竟不是登录状态的话很多东西是不允许访问和呈现出来的。
  2. 减少数据库的频繁查询,增加服务器性能,使得服务器更加健壮。
  3. 它可以在多个服务间共享,完全由应用管理,可以避开浏览器的同源策略
  4. 增加扩展性、安全性和减少服务器内存开销。传统的服务器验证是使用 cookie + session 验证,服务器需要每一次都验证客户端的请求去辨别客户端身份,并且还要创建一个记录将用户信息存储起来,然而随着现在科技发达,这种验证弊端也就显露出来了,例如用户增多从而引发内存资源消耗变大、CORS(跨域资源共享)和 CSRF(跨域请求伪造)等。

那么怎么用呢?

流程:

  1. 客户端的用户输入账户密码请求登录。
  2. 服务端收到请求并进行验证,成功则生成一个 token 值并返回给客户端。
  3. 客户端收到 token 值并将其存储,例如 本地存储:localStore 或 放在Cookie。
  4. 客户端每次请求都将 token 值放在请求头中发给服务器,服务器进行验证有效性。
  5. 成功则返回客户端请求的数据,失败可以让用户进行登录重新获取新的 token 值。

token的组成

一般 token 组成:

  1. Uid(用户身份的唯一标识)
  2. time(时间戳)
  3. sign(签名)

JWT 组成:

JWT(JSON Web Tokens) 读:jot

标准的组成:

  1. header(头部),参数主要包括:类型--JWT,签名的算法--HS256。
private static $header=array(
        'alg'=>'HS256', //生成signature的算法
        'typ'=>'JWT'    //类型
);
  1. poyload(负荷):一般是自己想要放置的数据(因为信息会暴露,不建议放敏感信息)。
    img
$time = time();
$tokenInfo = [
    'iss'=>'CIMS',
    'iat'=>$time,
    'nbf'=>$time+2,
    'jti'=>md5(uniqid('JWT').$time),
    'sub'=>$data,
    'exp'=> $time+7200
];
  1. sign(签名):为了防止被恶意篡改数据。
    /**
    • HMACSHA256签名 https://jwt.io/ 中HMACSHA256签名实现
    • @param string $input 为base64编码后连接而成的的header和poyload的字符串:base64UrlEncode(header).".".base64UrlEncode(tokenInfo)
    • @param string $key
    • @param string $alg 算法方式
    • @return mixed
      */
      private static function signature(string $input, string $key, string $alg = 'HS256')
      {
      $alg_config=array(
      'HS256'=>'sha256'
      );
      return self::base64UrlEncode(hash_hmac($alg_config[$alg], $input, $key,true));
      }

结果:一般会使用 base64 编码,中间用.隔开

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1aWQiOjEsIm5hbWUiOiJjZXNoaSIsImF1ZCI6IiIsImV4cCI6MTY4MTIyNDY0OCwiaWF0IjoxNjgxMjIxMDQ4LCJpc3MiOiIiLCJqdGkiOiJkN2UxYTBiNGU3MDZmODUxMjgzZWZkZWVlZjQ5MWEwOSIsIm5iZiI6MTY4MTIyMTA0OCwic3ViIjoiIn0.qRTyO1pYHHJxBNRwHUz032NWKKqS3C9dakOHASJyASk

总结

我们也可以在移动端使用,例如用Vue + express:

  1. 首先在 express 中安装 jsonwebtoken
npm install jsonwebtoken -S
  1. 生成 token 值并返回给前端:
    在 login 接口中加入
const token = jwt.sign({ info }, SECRET_KEY, { expiresIn: '24h' }); // SECRET_KEY 可以是自己定义的一个密钥,也可以是使用 crypto 包随机生成或者其他密钥
  1. 可以定义在全局然后使用白名单去除不需要验证的接口;这里定义一个验证 token 的中间件,需要使用 token 验证才能获取数据的接口才放上这个中间件:
const verifyToken = (req, res, next) => {
    const authHeader = req.headers['authorization'];
    const token = authHeader && authHeader.split(' ')[1];
    if (!token) {
        return res.status(401).json({ message: 'Missing token' });
    }
    try {
        jwt.verify(token, SECRET_KEY);
        console.log(jwt.verify(token, SECRET_KEY))
        next();
    } catch (error) {
        res.status(401).json({ message: 'Invalid token' });
    }
};
  1. 在前端登录成功后把返回的 token 值存储在 localStorage,至于存储在 localStorage 跟其他地方的区别可以看我八股文那篇文章中的浏览器部分:
localStorage.setItem('token', res.data.token);
  1. 可以使用拦截器把获取到的 token 值放在每次请求头中,Vue 是在 main.js 中配置,这里使用 axios 来发起请求,所以使用 axios 配置:
axios.interceptors.request.use(config => {
    // 获取localStorage中的token
    const token = localStorage.getItem('token');
    // 如果有token,则在请求头中添加Authorization字段
    if (token) {
        config.headers.Authorization = `Bearer ${token}`;
    }

    return config;
});
  1. 也可以在使用路由守卫判断是否已登录,在router/index.js中进行配置:
router.beforeEach((to, from, nex
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇laravel框架接口 下一篇linux使用php-ast方法

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目