token定义

参考

1、什么是Cookie?

  1. cookie指的就是浏览器里面能永久存储数据的一种数据存储功能。cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。
  2. Cookie有什么功能特点呢?在同一个页面中设置 Cookie,实际上是按从后往前的顺序进行的。如果要先删除一个
    Cookie,再写入一个 Cookie,则必须先写写入语句,再写删除语句,否则会出现错误 。
  3. Cookie是面向路径的。缺省路径 (path) 属性时,Web 服务器页会自动传递当前路径给浏览器,指定路径强制服务器使用设置的路径。在一个目录页面里设置的 Cookie 在另一个目录的页面里是看不到的 。
  4. Cookie 必须在 HTML 文件的内容输出之前设置;不同的浏览器 (Netscape Navigator、Internet Explorer) 对 Cookie 的处理不一致,使用时一定要考虑;客户端用户如果设置禁止 Cookie,则 Cookie 不能建立。 并且在客户端,一个浏览器能创建的 Cookie 数量最多为 300 个,并且每个不能超过 4KB,每个 Web 站点能设置的 Cookie 总数不能超过 20 个 。
  5. Cookie的生命周期呢?:Cookie可以保持登录信息到用户下次与服务器的会话,换句话说,下次访问同一网站时,用户会发现不必输入用户名和密码就已经登录了(当然,不排除用户手工删除Cookie)。而还有一些Cookie在用户退出会话的时候就被删除了,这样可以有效保护个人隐私。Cookie在生成时就会被指定一个Expire值,这就是Cookie的生存周期,在这个周期内Cookie有效,超出周期Cookie就会被清除。有些页面将Cookie的生存周期设置为“0”或负值,这样在关闭浏览器时,就马上清除Cookie,不会记录用户信息,更加安全。

2、什么是session?

  1. session就是会话。这个就类似于你和一个人交谈,你怎么知道当前和你交谈的是张三而不是李四呢?对方肯定有某种特征(长相等)表明他就是张三。
  2. session 也是类似的道理,服务器要知道当前发请求给自己的是谁。为了做这种区分,服务器就要给每个客户端分配不同的“身份标识sessionID”,然后客户端每次向服务器发请求的时候,都带上这个“身份标识sessionID”,服务器就知道这个请求来自于谁了。至于客户端怎么保存这个“身份标识sessionID”,可以有很多种方式,对于浏览器客户端,大家都默认采用 cookie 的方式。
  3. 服务器使用session把用户的信息临时保存在了服务器上,用户离开网站后session会被销毁。这种用户信息存储方式相对cookie来说更安全,可是session有一个缺陷:如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失。
  4. JSP使用一个叫HttpSession的对象实现同样的功能。HTTPSession 是一个建立在cookies 和URL-rewriting上的高质量的界面。Session的信息保存在服务器端。
  5. Session的id保存在客户机的cookie中。事实上,在许多服务器上,如果浏览器支持的话它们就使用cookies,但是如果不支持或废除了的话就自动转化为URL-rewriting
  6. session自动为每个流程提供了方便地存储信息的方法。

3、Httpsession具有如下API:

  1. getId 此方法返回唯一的标识,这些标识为每个session而产生。当只有一个单一的值与一个session联合时,或当日志信息与先前的sessions有关时,它被当作键名用。
  2. GetCreationTime 返回session被创建的时间。最小单位为千分之一秒。为得到一个对打印输出很有用的值,可将此值传给Date
    constructor 或者GregorianCalendar的方法setTimeInMillis.
  3. GetLastAccessedTime 返回session最后被客户发送的时间。最小单位为千分之一秒。
  4. GetMaxInactiveInterval 返回总时间(秒),负值表示session永远不会超时。
  5. getAttribute 取一个session相联系的信息。(在jsp1.0中为 getValue)
  6. Integer item = (Integer)session.getAttribute(“item”) //检索出session的值并转化为整型
  7. setAttribute 提供一个关键词和一个值。会替换掉任何以前的值。(在jsp1.0中为putValue)
  8. session.setAttribute(“ItemValue”, itemName); // ItemValue 必须不是must简单类型
  9. 在应用中使用最多的是getAttribute和setAttribute.

4、传统身份验证(session)

  1. HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用。这里我们把用户看成是客户端,客户端使用用户名还有密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下。
  2. 解决的方法就是,当用户请求登录的时候,如果没有问题,我们在服务端生成一条记录,这个记录里可以说明一下登录的用户是谁,然后把这条记录的 ID 号发送给客户端,客户端收到以后把这个 ID 号存储在 Cookie 里,
  3. 下次这个用户再向服务端发送请求的时候,可以带着这个 Cookie ,这样服务端会验证一个这个 Cookie 里的信息,看看能不能在服务端这里找到对应的记录,如果可以,说明用户已经通过了身份验证,就把用户请求的数据返回给客户端。
  4. 上面说的就是 Session,我们需要在服务端存储为登录的用户生成的 Session ,这些 Session 可能会存储在内存,磁盘,或者数据库里。我们可能需要在服务端定期的去清理过期的 Session

5、什么是Token?

    Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。

基于 Token 的身份验证

  1. 使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。流程是这样的:
  2. 客户端使用用户名跟密码请求登录
  3. 服务端收到请求,去验证用户名与密码
  4. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  5. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  6. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  7. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
  8. APP登录的时候发送加密的用户名和密码到服务器,服务器验证用户名和密码,如果成功,以某种方式比如随机生成32位的字符串作为token,存储到服务器中,并返回token到APP,以后APP请求时,
  9. 凡是需要验证的地方都要带上该token,然后服务器端验证token,成功返回所需要的结果,失败返回错误信息,让他重新登录。其中服务器上token设置一个有效期,每次APP请求的时候都验证token和有效期。

6、由此我们可以扩展一个问题:

  1. 服务器上的token存储到数据库中,每次查询会不会很费时。如果不存储到数据库,应该存储到哪里呢。
  2. 客户端得到的token肯定要加密存储的,发送token的时候再解密。存储到数据库还是配置文件好呢
  3. token是个易失数据,丢了无非让用户重新登录一下,可以放到 MSSQL/MySQL 的内存表里(不过据说mysql的内存表性能提升有限),可以放到 Memcache里,可以放到redis里,放到 OpenResty 的变量字典里(只要你有信心不爆内存)。
  4. 你认为用数据库来保持token查询时间太长,会成为你系统的瓶颈或者隐患,可以放在内存当中。
  5. 比如memcached、redis,KV方式很适合你对token查询的需求。
  6. 这个不会太占内存,比如你的token是32位字符串,要是你的用户量在百万级或者千万级,那才多少内存。
  7. 要是数据量真的大到单机内存扛不住,或者觉得一宕机全丢风险大,只要这个token生成是足够均匀的,高低位切一下分到不同机器上就行,内存绝对不会是问题。

7、Token安全问题

  1. 在存储的时候把token进行对称加密存储,用时解开。
  2. 将请求URL、时间戳、token三者进行合并加盐签名,服务端校验有效性。
  3. 这两种办法的出发点都是:窃取你存储的数据较为容易,而反汇编你的程序hack你的加密解密和签名算法是比较难的。然而其实说难
  4. 也不难,所以终究是防君子不防小人的做法。话说加密存储一个你要是被人扒开客户端看也不会被喷明文存储…… 方法1它拿到存储的密文解不开、方法2它不知道你的签名算法和盐,两者可以结合食用。
  5. 但是如果token被人拷走,他自然也能植入到自己的手机里面,那到时候他的手机也可以以你的身份来用着,这你就瞎了。
  6. 于是可以提供一个让用户可以主动expire一个过去的token类似的机制,在被盗的时候能远程止损。
  7. 在网络层面上token明文传输的话会非常的危险,所以建议一定要使用HTTPS,并且把token放在post body里

token的优点

  1. 支持跨域访问: Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输。
  2. 无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息。
  3. 更适用CDN: 可以通过内容分发网络请求你服务端的所有资料(如:javascript,HTML,图片等),而你的服务端只要提供API即可。
  4. 去耦: 不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可。
  5. 更适用于移动应用: 当你的客户端是一个原生平台(iOS, Android,Windows8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
  6. **CSRF:**因为不再依赖于Cookie,所以你就不需要考虑对CSRF(跨站请求伪造)的防范。
  7. 性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析要费时得多。
  8. 不需要为登录页面做特殊处理: 如果你使用Protractor 做功能测试的时候,不再需要为登录页面做特殊处理。
  9. **基于标准化:**你的API可以采用标准化的 JSON Web Token (JWT). 这个标准已经存在多个后端库(.NET, Ruby, Java,Python, PHP)和多家公司的支持(如:Firebase,Google, Microsoft)。
  10. **跨语言支持:**因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。
  11. 存储非敏感信息因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。
  12. 字节占用小,便于传输便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。
  13. 易扩展它不需要在服务端保存会话信息, 所以它易于应用的扩展。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 Vue 3 + Pinia 中,可以使用 Pinia 来定义并管理全局状态。首先,需要创建一个 `store` 实例,并定义 `state` 和 `mutations`: ```typescript import { defineStore } from 'pinia'; interface AuthState { token: string | null; } export const useAuthStore = defineStore({ id: 'auth', state: (): AuthState => ({ token: null, }), mutations: { setToken(state: AuthState, token: string | null) { state.token = token; }, }, }); ``` 在上面的代码中,我们定义了一个名为 `useAuthStore` 的 store,并指定了它的 `id` 为 `auth`。`state` 中定义了一个名为 `token` 的属性,初始值为 `null`。`mutations` 中定义了一个名为 `setToken` 的 mutation,用于设置 `token` 的值。 接下来,我们可以在 store 中定义一个 `getters`,用于获取 `token` 的值: ```typescript import { defineStore } from 'pinia'; interface AuthState { token: string | null; } export const useAuthStore = defineStore({ id: 'auth', state: (): AuthState => ({ token: null, }), mutations: { setToken(state: AuthState, token: string | null) { state.token = token; }, }, getters: { getToken(state: AuthState) { return state.token; }, }, }); ``` 现在,我们在 store 中定义了一个名为 `getToken` 的 getter,用于获取 `token` 的值。在组件中,我们可以使用 `useAuthStore` 的 `useStore` 辅助函数来创建一个 store 实例: ```typescript import { useAuthStore } from '@/store'; export default { setup() { const authStore = useAuthStore(); const setToken = (token: string | null) => { authStore.setToken(token); }; const getToken = () => { return authStore.getToken; }; return { setToken, getToken, }; }, }; ``` 这样,在组件中就可以通过 `setToken` 和 `getToken` 方法来设置和获取 `token` 的值了。例如,在登录成功后设置 `token` 的值: ```typescript import { useAuthStore } from '@/store'; export default { setup() { const authStore = useAuthStore(); const handleLogin = async () => { // 发送登录请求并获取 token const token = 'xxxxx'; authStore.setToken(token); }; return { handleLogin, }; }, }; ``` 在其他组件中,我们也可以使用 `getToken` 方法来获取 `token` 的值: ```typescript import { useAuthStore } from '@/store'; export default { setup() { const authStore = useAuthStore(); const token = authStore.getToken; return { token, }; }, }; ``` 这样,就可以在 Vue 3 + Pinia 应用中定义和管理 `token` 了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值