正文开始之前,我们先要了解一个概念,就是什么是 登录态。
主流Web应用比如浏览器是基于http协议的,而http协议是 无状态 的。什么是 无状态?就是服务器不知道是谁发送了这个http请求,无法识别区分用户身份。
所以登录态就是服务端用来区分用户身份,同时对用户进行记录的技术方案。
那怎么实现用户的登录态呢?常见的实现流程如下:

流程有了,如何实现呢?
常见的方案有HTTP基本认证、Cookie和Session认证、Token认证、单点登录认证等,下面一一介绍。
HTTP基本认证是HTTP协议本身提供了一种服务端对客户端进行用户身份验证的方法。 流程如下:

sequenceDiagram
autonumber
客户端->>服务端:Get / HTTP/1.1 Host:www.qq.com
服务端->>客户端:HTTP/1.1 401 Unauthorised WWW-Authenticate: Basic realm="qq.com"
客户端->>客户端:弹出登录窗口
客户端->>服务端:Get / HTTP/1.1 Host:www.qq.com Authorization: Basic xxxxxx
服务端->>客户端:验证成功,返回用户数据
WWW-Authenticate: Basic realm="qq.com",弹出用户名和密码输入框要求用户进行验证。Base64 格式发送给服务端。这是一种比较简单的验证用户身份的方式,甚至不需要写代码,只要后端服务器配置一下即可。
优点:兼容性好,主流浏览器都支持
缺点:
先了解两个概念,Cookie和Session是什么呢? 上面说到HTTP是一种无状态协议,而Cookie和Session可以弥补 HTTP 的无状态特性。
Cookie是客户端请求服务端时,由服务端创建并由客户端存储和管理的小文本文件。具体流程如下:
Session是客户端请求服务端时服务端会为这次请求创建一个数据结构,这个结构可以通过内存、文件、数据库等方式保存。具体流程如下:

Token又叫令牌,是服务端生成用来验证客户端身份的凭证,客户端每次请求都携带Token。 Token一般由以下数据组成:
uid(用户唯一的身份标识)
time(当前时间的时间戳)
sign(签名,由token的前几位+盐用哈希算法压缩成一定长的十六进制字符串)

3.3里说到为了避免被盗用Token一般有效期比较短。但是有效期太短会造成客户端不断重新登录,体验太差。有没有什么办法可以解决这个问题呢?
那就是再来一个Token,一个专门生成Token的Token,称为 Refresh Token。
流程如下:

3.3、3.4里服务端校验客户端发过来的Token是否有效时,可能会查询数据库来验证。如果每次请求都要查询数据库,可能会带来额外性能消耗。
那这个有没有办法优化呢?
答案是有的,那就是JWT(JSON Web Token)。JWT 是 Auth0 提出的通过 对JSON进行加密签名 来实现授权验证的方案。
JWT也是一种Token,由三部分组成: Header头部 、 Payload负载 和 Signature签名。它是一个很长的字符串,中间用点( . )分隔成三个部分,列如 :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Header头部:
{
"alg": "Hash算法(HMAC、SHA256或RSA)",
"typ": "Token的类型(JWT)"
}
Payload负载:
{
"iss": "签发人(issuer)",
"exp": "过期时间(expiration time)",
"sub": "主题(subject)",
"aud": "受众(audience)",
"nbf": "生效时间(not before)",
"iat": "签发时间(issued at)",
"jti": "编号(JWT ID)",
"uid": "自定义字段(可以存储用户ID等)",
}
Signature 签名:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret //设置的密钥
)
JWT的流程和Token的基本一样,因为已经携带了客户端信息(如用户ID等),所以服务端校验Token时不需要查询数据库了。
上面说的都是同一个域名(或同一主域)下,通过Cookie或Token携带凭证实现登录态管理。但是如果有很多域名,如何实现用户在一个域名下登录后,访问另一个域名也能自动登录呢?
这就是单点登录问题(Single Sign On)
要实现SSO,需要有一个CAS(Central Authentication Service)中央授权服务(假设域名为cas.com)来提供统一的登录功能。
假如现在有域名http://abc.com和http://123.com要实现互相自动登录。流程如下:


总结:
以上总结4种了常见的登录方案,还有OAuth2.0、扫码登录等方式,后续还会继续更新,敬请期待。。。
作者:yanweiyao
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
文章目录git常用命令(简介,详细参数往下看)Git提交代码步骤gitpullgitstatusgitaddgitcommitgitpushgit代码冲突合并问题方法一:放弃本地代码方法二:合并代码常用命令以及详细参数gitadd将文件添加到仓库:gitdiff比较文件异同gitlog查看历史记录gitreset代码回滚版本库相关操作远程仓库相关操作分支相关操作创建分支查看分支:gitbranch合并分支:gitmerge删除分支:gitbranch-ddev查看分支合并图:gitlog–graph–pretty=oneline–abbrev-commit撤消某次提交git用户名密码相关配置g
我正在构建一个应用程序,想知道是否将未使用的对象设置为nil是生产级编码中的常见做法。我知道这只是垃圾收集器的提示,并不总是处理对象。 最佳答案 根据这个thread如果您使用完一个成员对象,将其设置为nil将引发被引用对象被垃圾回收。如果它是局部变量,方法exit将做同样的事情。也就是说,如果您要求将成员显式设置为nil,我会质疑您的设计。 关于ruby-将对象设置为nil是否很常见?,我们在StackOverflow上找到一个类似的问题: https://
我最近与一位同事讨论了以下Ruby语法:value=ifa==0"foo"elsifa>42"bar"else"fizz"end我个人并没有看到太多这种逻辑,但我的同事指出,这实际上是一种相当普遍的Rubyism。我试着用谷歌搜索这个主题,但没有找到任何文章、页面或SO问题来讨论它,这让我相信这可能是一种非常实际的技术。然而,另一位同事发现语法令人困惑,而是将上面的逻辑写成这样:ifa==0value="foo"elsifa>42value="bar"elsevalue="fizz"end缺点是value=的重复声明和隐式elsenil的丢失,如果我们想使用它的话。这也感觉它与Ruby
我有一个应用程序正在从Ruby迁移到JRuby(由于需要通过Java提供更好的Web服务安全支持)。我使用的gem之一是daemons创建后台作业。问题在于它使用fork+exec来创建后台进程,但这对JRuby来说是禁忌。那么-是否有用于创建后台作业的替代gem/wrapper?我目前的想法是只从shell脚本调用rake并让rake任务永远运行......提前致谢,克里斯。更新我们目前正在使用几个与Java线程相关的包装器,即https://github.com/jmettraux/rufus-scheduler和https://github.com/philostler/acts
我需要从站点抓取数据,但它需要我先登录。我一直在使用hpricot成功地抓取其他网站,但我是使用mechanize的新手,我真的对如何使用它感到困惑。我看到这个例子经常被引用:require'rubygems'require'mechanize'a=Mechanize.newa.get('http://rubyforge.org/')do|page|#Clicktheloginlinklogin_page=a.click(page.link_with(:text=>/LogIn/))#Submittheloginformmy_page=login_page.form_with(:act
我想在随机字符串前后添加一个空格。我试过使用"Random_string".center(1,"")但它不起作用。谢谢 最佳答案 我发现这是最优雅的解决方案:padded_string="#{random_string}"走简单的路没有错。 关于ruby-在ruby中的字符串前后添加空格?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/3357897/
安全产品安全网关类防火墙Firewall防火墙防火墙主要用于边界安全防护的权限控制和安全域的划分。防火墙•信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。防火墙是一个由软件和硬件设备组合而成,在内外网之间、专网与公网之间的界面上构成的保护屏障。下一代防火墙•下一代防火墙,NextGenerationFirewall,简称NGFirewall,是一款可以全面应对应用层威胁的高性能防火墙,提供网络层应用层一体化安全防护。生产厂家•联想网御、CheckPoint、深信服、网康、天融信、华为、H3C等防火墙部署部署于内、外网编辑额,用于权限访问控制和安全域划分。UTM统一威胁管理(Un
目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'
我为Devise用户和管理员提供了不同的模型。我也在使用Basecamp风格的子域。除了我需要能够以用户或管理员身份进行身份验证的一些Controller和操作外,一切都运行良好。目前我有authenticate_user!在我的application_controller.rb中设置,对于那些只有管理员才能访问的Controller和操作,我使用skip_before_filter跳过它。不幸的是,我不能简单地指定每个Controller的身份验证要求,因为我仍然需要一些Controller和操作才能被用户或管理员访问。我尝试了一些方法都无济于事。看来,如果我移动authentica