跳到主要内容

登录机制相关

HTTP Cookie(也叫 Web Cookie或浏览器 Cookie)是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,如保持用户的登录状态。Cookie 使基于无状态的 HTTP 协议记录稳

Cookie 主要用于以下三个方面:

  • 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
  • 个性化设置(如用户自定义设置、主题等)
  • 浏览器行为跟踪(如跟踪分析用户行为等)

Cookie的作用就是用于解决:如何记录客户端的用户信息,在用户下一次访问该页面时,可以在 cookie中读取用户访问记录。

cookie使用

  • 我们知道cookie的作用就是可以记录客户端的用户信息,在用户下一次访问该页面时,可以在 cookie中读取用户访问记录。
    • 那么我们可以实现一些功能,如弄一个 下次自动登录勾选,将账号和密码保存到cookie,下次登陆自动显示到表单内
    • 点击忘记密码则清空之前保存到cookie的值,下次登陆需要手动输入
    • 前端可以把token存储到cookie中,保持登录状态,而不用保持到localstorage中,以免XSS攻击
    • 前端每次路由跳转,判断 cookie有无 token ,没有则跳转到登录页,有则请求获取用户信息,改变登录状态

什么是 Session​

Session 代表着服务器和客户端一次会话的过程。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当客户端关闭会话,或者 Session 超时失效时会话结束。

cookie和session的区别​

  • 作用范围不同,Cookie 保存在客户端(浏览器),Session 保存在服务器端。
  • 存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意数据类型,一般情况下我们可以在 Session 中保持一些常用变量信息,比如说 UserId 等。
  • 有效期不同,Cookie 可设置为长时间保持,比如我们经常使用的默认登录功能,Session 一般失效时间较短,客户端关闭或者 Session 超时都会失效。
  • cookie的过期时间:1.不设置过期时间,会存在内存里,浏览器关闭即失效。2.设置过期时间,会存在硬盘里,一直到过期时间才失效。
  • session的过期时间如果Session对象设置了超时时间,Session对象超过此时间会被销毁。如果没有设置默认30分钟会被销毁(服务器默认配置)
  • 隐私策略不同,Cookie 存储在客户端,比较容易遭到不法获取,早期有人将用户的登录名和密码存储在 Cookie 中导致信息被窃取;Session 存储在服务端,安全性相对 Cookie 要好一些。
  • 存储大小不同, 单个 Cookie 保存的数据不能超过 4K,Session 可存储数据远高于 Cookie。
  • cookie不是很安全,用来存放用户不太敏感的数据信息,考虑到安全性的话应使用session

cookie的使用场景?存什么信息?​

生成:

  • cookie由服务器生成,在客户端以key-value形式保存用户信息

使用:

  • 用于响应头和请求头中:由服务器在响应头中设置,客户端保存,并在发送请求时请求头中带上cookie

场景:

登录:

  • 当用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token,拿到token之后(我会将这个token存贮到cookie中,保证刷新页面后能记住用户登录状态),前端会根据token再去拉取一个 user_info 的接口来获取用户的详细信息(如用户权限,用户名等等信息)
  • 退出登录:只需要把token清除掉即可,就会退出登录,然后跳转到登录页面

权限:

  • 权限验证:通过token获取用户对应的 role,动态根据用户的 role 算出其对应有权限的路由

说起来为什么需要 Cookie ,这就需要从浏览器开始说起,我们都知道浏览器是没有状态的(HTTP 协议无状态),这意味着浏览器并不知道是张三还是李四在和服务端打交道。这个时候就需要有一个机制来告诉服务端,本次操作用户是否登录,是哪个用户在执行的操作,那这套机制的实现就需要 Cookie 和 Session 的配合。

1、用户第一次请求服务器的时候,服务器根据用户提交的相关信息,创建创建对应的 Session ,请求返回时将此 Session 的唯一标识信息 SessionID 返回给浏览器,浏览器接收到服务器返回的 SessionID 信息后,会将此信息存入到 Cookie 中,同时 Cookie 记录到SessionID 属于哪个域名。

2、当用户第二次/n次访问服务器的时候,请求会自动判断此域名下是否存在 Cookie 信息,如果存在自动将 Cookie 信息也发送给服务端,服务端会从 Cookie 中获取 SessionID,再根据 SessionID 查找对应的 Session 信息,如果没有找到说明用户没有登录或者登录失效,如果找到 Session 证明用户已经登录可执行后面操作。

根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

本地存储和cookie之间的区别​

  • 本地存储:localStorage、sessionStorage

  • localStorage(本地存储)生命周期是永久,这意味着除非用户显示在浏览器提供的UI上清除localStorage信息,否则这些信息将永远存在。仅在客户端(即浏览器)中保存,不参与和服务器的通信

  • sessionStorage(会话存储)生命周期为页面会话期间可用,关闭页面或浏览器之后,那么所有通过sessionStorage存储的数据也就被清空了。

  • cookie:

    • cookie 默认如果不设置有效期,那么他默认是随着窗口关闭而清除;存放的数据大约为4K左右;
    • cookie在服务器和客户端都可以访问
    • cookie 存储的内容会保留在 HTTP 请求的 Header 中
    • cookie在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
  • 区别:

      1. cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存

      2. 作用域不同:sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的

      3. 存储大小不同:sessionStorage和localStorage 存放数据是5M,cookie存放数据约4K

Token​

  • token是一种用于身份验证和授权的令牌。

  • 通常是通过用户使用用户名和密码进行登录后返回的。一旦用户被验证,服务器会生成一个token并将其发送回前端应用程序。

    • token通常是一个长字符串,包含有关用户和权限的相关信息
    • 可通过jwt解码token,可看到用户的相关信息
  • token可以预防CSRF攻击 (跨站请求伪造)

    • CSRF 攻击是一种利用用户已经登录的身份来发送恶意请求的

    • 通过token来验证用户的身份

    • 如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求

Token的有效期是多长时间?​

获取token的时候,服务器会把token字符串和有效期(expires_in )一起返回给您,token 默认有效期为7天,您可以在获取到Token后再自己服务器做一个缓存,快到期后重新获取。有效期验证可以用当前时间戳减去获取到token的时间戳与token有效期进行对比

Token是如何生成?​

  • 浏览器第一次访问服务器,根据传过来的唯一标识userId,服务端会通过一些算法,如常用的HMAC-SHA256算法,然后加一个密钥,生成一个token,然后通过BASE64编码一下之后将这个token发送给客户端;客户端将token保存起来,下次请求时,带着token,服务器收到请求后,然后会用相同的算法和密钥去验证token,如果通过,执行业务操作,不通过,返回不通过信息

Token存储在Cookie还是LocalStorage?​

http://blog.itpub.net/10742815/viewspace-2142725/

  • 由于LocalStorage 和 SessionStorage 都可以被 javascript 访问,所以容易受到XSS攻击

  • 将Token存储于Cookie!!!!​

1、设置HttpOnly标志后,Cookie将无法通过JavaScript访问,这可以防止XSS(跨站脚本攻击)攻击,因为攻击者无法通过脚本获取Cookie中的敏感信息。

2、设置Secure标志后,Cookie只在通过HTTPS协议进行加密的安全连接时传输,保护了数据在传输过程中的安全性。

无感登录​

假设一个页面用户比如编辑页/写文章需要停留很久 (停留时长 > token有效时长)

  • 当登录成功之后,会返回2个token (access_token、refresh_token)
  • 当access_token过期时,通过refresh_token来刷新
  • 刷新接口,会返回access_token和refesh_token 两个接口

access_token一般过期时间设置的比较短 (比如30分钟、一天)

refresh_token的设置的过期时间比较长 (比如7天)

  • 如果设置了7天,只需要在7天内访问一次,就能刷新token,再续7天
  • 如果超过了7天没访问,那么refresh_token也会过期,这时候就需要重新登录了

不希望用户重新登录,需要如何解决?

  • 1、可以在响应进行拦截,判断token是否过期,调用刷新token的接口
    • 需要判断当前请求 不是刷新token的请求,才去调用刷新token 【否在会出现死循环】
      • 因为当刷新token (refresh_token)也过期了,那么会一直进入401判断,会不断请求刷新token,造成死循环
      • 需要在判断401请求刷新token的同时,还需要判断 当前接口是否为刷新token的接口
        • 1、可以通过接口地址判断
        • 2、可以在刷新token加一个额外的配置,来判断是否为刷新token
  • 2、后端可以返回过期的时间,前端判断token是否过期, 然后再去调用刷新token的接口
  • 3、定时刷新token接口

使用刷新Token(Refresh Token)​

在响应进行拦截,判断 Token 是否过期,调用刷新 Token 的接口

  • 可以在每次请求中拦截响应,检查 Token 是否过期,然后调用刷新 Token 的接口。这可以确保用户在页面停留期间不会意外地登出

后端判断token登录失效之后,不返回401,而是返回新token,会有什么问题?​

  • 前端不知道 Token 失效

  • 无法识别 Token 被盗用

    • 如果攻击者获取了用户的 Token,后端返回新 Token 而不返回 401 错误,攻击者可能会持续使用被盗取的 Token,从而获得不受限的访问权限

什么情况会去到登录页?​

  • 如果设置的refresh_token过期了,这时候就需要重新登录了

刷新token之后,如何让401的接口重新请求​

  • 需要把401的接口请求放到数组队列中,刷新token之后,就把这个401队列的请求重新去请求

第三方登录(扫码登录)​

场景:

  • 便捷登录(快速登录)
  • 提高接口安全,降低登录接口的压力与风险

前端:

  • 向后端请求二维码,后端返回图片
  • 前端需要轮询消息,后端返回是否登录成功/失败
  • 轮询判断是否有登录、拿到登录状态信息

用户信息从哪里来,码怎么与用户对应?​

1、用户信息可以从第三方登录平台获取。

2、在用户扫描二维码并授权登录后,第三方平台会返回一个授权码或访问令牌。

3、通过使用这个授权码或令牌,你可以向第三方平台发送请求,获取用户的基本信息,例如昵称、头像等。

3、码与用户的对应关系可以通过在第三方平台注册应用时所获得的应用ID和密钥,以及在后端维护的会话状态进行关联

为什么要轮询,websocket行不行​

  • 轮询需要客户端以一定的时间间隔向服务器发送请求,查询登录状态是否已经改变
  • WebSocket是一种全双工通信协议,可以在客户端与服务器之间建立长连接,因此,使用WebSocket可以更高效地实现实时消息推送

怎么判断用户是否登录成功​

判断用户是否登录成功可以根据实际应用的需求和第三方平台所提供的接口来确定

  • 可以通过接收到的授权码或访问令牌,向第三方平台发送验证请求以确认登录的有效性
  • 第三方平台会返回相应的验证结果,来判断用户是否登录成功