zoukankan      html  css  js  c++  java
  • API 接口设计中 Token 类型的分类与设计

    在实际的网站设计中我们经常会遇到用户数据的验证和加密的问题,如果实现单点,如果保证数据准确,如何放着重放,如何防止CSRF等等

    其中,在所有的服务设计中,都不可避免的涉及到Token的设计。

    目前,基于Token的生成方,我们把Token生成分为两种类型。

    1、基于用户/网站,可见的加密请求方式

    2、基于服务器间通讯的不可见加密请求方式(API Token)

    其中,网页/APP访问又分为 登录态和非登录态 两种请求区别。

    (非登录态请求要求用户访问页面时会随机生成唯一且有时效性的token,该token在每次请求时都是不同)

    (登录状态中,token会保存一定的时间,页面中的token会作为用户身份识别)

    虽说两者作用有一定的区别,但是实现的原理是相同的。

    1、非登录状态

    原理:

    非登录状态中,防止服务器资源被重复利用,我们在前端页面中会添加一步建立初始Session的过程,该过程来确保下一步关键请求不被利用。

    一般这种验证方式用于体验页面,如:视频播放页面,项目或功能展示页面等

    优点:

    目的就是有点,防止token被盗用,重复请求服务器资源(类似于抖音视频播放时的签名算法作用)

    缺点:

    所有前端加密都有被破解的可能,需要对具体的JS进行混淆,同时添加https和来源判断

    2、登录状态

     登录状态的Token

    登录态token 通过服务器生成:

    Encode(MD5({session}+{用户信息摘要}+{Timestamp})+TimeStamp)
    

      

    联合Redis 刷新用户登录时长及token有效时长。Redis设置自动过期时间。

    验证方法:

    decode(Token)->sign+TimeStamp
    if(sign===MD5({session}+{用户信息摘要}+{Timestamp})){
      // XXXX
    }

    (防止弱语言的判断逻辑,验证PW和Token要用=== 强类型判断)

    退出登录:删除Redis 键值

    单点登录:重新登录时信息更新,用户信息摘要不变,自动刷新Redis的Token值和有效期

    3、API 非对称加密

    api的非对称加密常用于服务器之间的请求,双方各自保存私钥和公钥。API接口中常体现于【APP_ID,APP_KEY|APP_SECRET】

    Token 生成算法:

        /**
         * 生成token
         * @param $user_info string 
         * @param $app_key string  app_key
         * @param $app_id int app_id
         * @return string
         */
        public function generate_access_token($user_info , $app_key, $app_id)
        {
            $time = time();
            $sign = sha1($time . $advertiser_id . $app_key);
            $token = base64_encode("{$time},{$user_info },{$app_id},{$sign}");
            return $token;
        }

    Token解析方法:

    解密的方法中对时效性做了一分钟的验证,实际项目中可以根据情况开放失效的设置。

        /**
         * 解析token
         * @param $access_token
         * @return array
         */
        public function analysis_access_token($access_token)
        {
    
            $token_array = base64_decode($access_token);
            $token_array = explode(',', $token_array);
            $time = $token_array[0];
            $user_info = $token_array[1];
            $app_id = $token_array[2];
            $sign = $token_array[3];
    
            if ($time < (time() - 60) || $time > (time() + 60)) {
                call_back(1101, 'Access Token expire !token=' . $access_token);
            }
    
            global $third_platform_app_key;// app_id-app_key对应表
    
            if (!isset($third_platform_app_key[$app_id])) {
                call_back(1101, 'Access Token App id Error!token=' . $access_token);
            }
    
            $app_key = $third_platform_app_key[$app_id];
    
            $local_sign = sha1($time . $user_info . $app_key);
    
            if ($local_sign === $sign) {
                return [
                    'access_token' => $access_token,
                    'user_info' => $user_info,
                    'time' => $time,
                    'app_id' => $app_id,
                    'app_key' => $app_key,
                ];
            } else {
                call_back(1101, 'Access Token Sign Error!token=' . $access_token);
            }
        }

     改Token方式要求每次请求都需要生成新的token来确保请求的时效性

    另外:为了加强API接口请求的完整性,我们也会对请求内容进行字段排序后摘要验证。(详情参考:https://open.taobao.com/docV2.htm?docId=101617&docType=1)

    今天的普及到这里就结束啦,谢谢大家,也欢迎大家留言讨论。

  • 相关阅读:
    C语言网 蓝桥杯 1117K-进制数
    C语言网蓝桥杯1116 IP判断
    LeetCode 面试题14- II. 剪绳子 II
    LeetCode 面试题06. 从尾到头打印链表
    LeetCode 面试题05. 替换空格
    LeetCode 面试题04. 二维数组中的查找
    LeetCode 面试题03. 数组中重复的数字
    LeetCode 3. 无重复字符的最长子串
    LeetCode 202. 快乐数
    LeetCode 154. 寻找旋转排序数组中的最小值 II
  • 原文地址:https://www.cnblogs.com/Bobdong/p/9476566.html
Copyright © 2011-2022 走看看