HTTP Basic Auth
在HTTP中,基本认证是一种用来允许Web浏览器或其他客户端程序在请求时提供用户名和口令形式的身份凭证的一种登录验证方式,通常用户名和明码会通过HTTP头传递。
OAuth
名词定义
-
Third-party application: 第三方应用程序,又称"客户端"(client)
-
HTTP service:HTTP服务提供商
-
Resource Owner:资源所有者,通常称"用户"(user)。
-
User Agent:用户代理,比如浏览器。
-
Authorization server:认证服务器,即服务提供商专门用来处理认证的服务器。
-
Resource server:资源服务器,即服务提供商存放用户生成的资源的服务器。它与认证服务器,可以是同一台服务器,也可以是不同的服务器。
JWT 认证
JWT 特点
-
体积小,因而传输速度快
-
传输方式多样,可以通过URL/POST参数/HTTP头部等方式传输
-
严格的结构化。它自身(在 payload 中)就包含了所有与用户相关的验证消息,如用户可访问路由、访问有效期等信息,服务器无需再去连接数据库验证信息的有效性,并且 payload 支持为你的应用而定制化。
-
支持跨域验证,可以应用于单点登录。
JWT原理
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
1. 头部(Header)
// 包括类别(typ)、加密算法(alg);
{
"alg": "HS256",
"typ": "JWT"
}
-
声明类型,这里是jwt
-
声明加密的算法 通常直接使用 HMAC SHA256
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2. 载荷(payload)
-
标准中注册声明
-
公共的声名
-
私有的声明
// 包括需要传递的用户信息;
{ "iss": "Online JWT Builder",
"iat": 1416797419,
"exp": 1448333419,
"aud": "www.gusibi.com",
"sub": "uid",
"nickname": "goodspeed",
"username": "goodspeed",
"scopes": [ "admin", "user" ]
}
-
iss: 该JWT的签发者,是否使用是可选的;
-
sub: 该JWT所面向的用户,是否使用是可选的;
-
aud: 接收该JWT的一方,是否使用是可选的;
-
exp(expires): 什么时候过期,这里是一个Unix时间戳,是否使用是可选的;
-
iat(issued at): 在什么时候签发的(UNIX时间),是否使用是可选的;
-
nbf (Not Before):如果当前时间在nbf里的时间之前,则Token不被接受;一般都会留一些余地,比如几分钟;,是否使用是可选的;
-
jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。
eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0MTY3OTc0MTksImV4cCI6MTQ0ODMzMzQxOSwiYXVkIjoid3d3Lmd1c2liaS5jb20iLCJzdWIiOiIwMTIzNDU2Nzg5Iiwibmlja25hbWUiOiJnb29kc3BlZWQiLCJ1c2VybmFtZSI6Imdvb2RzcGVlZCIsInNjb3BlcyI6WyJhZG1pbiIsInVzZXIiXX0
3. 签名(signature)
// 根据alg算法与私有秘钥进行加密得到的签名字串;
// 这一段是最重要的敏感信息,只能在服务端解密;
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
SECREATE_KEY
)
-
header (base64后的)
-
payload (base64后的)
-
secret
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJKb2huIFd1IEpXVCIsImlhdCI6MTQ0MTU5MzUwMiwiZXhwIjoxNDQxNTk0NzIyLCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJqcm9ja2V0QGV4YW1wbGUuY29tIiwiZnJvbV91c2VyIjoiQiIsInRhcmdldF91c2VyIjoiQSJ9
pq5IDv-yaktw6XEa5GEv07SzS9ehe6AcVSdTj0Ini4o
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJPbmxpbmUgSldUIEJ1aWxkZXIiLCJpYXQiOjE0MTY3OTc0MTksImV4cCI6MTQ0ODMzMzQxOSwiYXVkIjoid3d3Lmd1c2liaS5jb20iLCJzdWIiOiIwMTIzNDU2Nzg5Iiwibmlja25hbWUiOiJnb29kc3BlZWQiLCJ1c2VybmFtZSI6Imdvb2RzcGVlZCIsInNjb3BlcyI6WyJhZG1pbiIsInVzZXIiXX0.pq5IDv-yaktw6XEa5GEv07SzS9ehe6AcVSdTj0Ini4o
JWT 使用场景
python 使用JWT实践
import jwt
import time
# 使用 sanic 作为restful api 框架
def create_token(request):
grant_type = request.json.get('grant_type')
username = request.json['username']
password = request.json['password']
if grant_type == 'password':
account = verify_password(username, password)
elif grant_type == 'wxapp':
account = verify_wxapp(username, password)
if not account:
return {}
payload = {
"iss": "gusibi.com",
"iat": int(time.time()),
"exp": int(time.time()) + 86400 * 7,
"aud": "www.gusibi.com",
"sub": account['_id'],
"username": account['username'],
"scopes": ['open']
}
token = jwt.encode(payload, 'secret', algorithm='HS256')
return True, {'access_token': token, 'account_id': account['_id']}
def verify_bearer_token(token):
# 如果在生成token的时候使用了aud参数,那么校验的时候也需要添加此参数
payload = jwt.decode(token, 'secret', audience='www.gusibi.com', algorithms=['HS256'])
if payload:
return True, token
return False, token
总结
预告,下一篇是介绍小程序中使用 JWT 的认证流程及实现。
参考链接
-
HTTP基本认证:https://zh.wikipedia.org/wiki/HTTP基本认证
-
访问需要HTTP Basic Authentication认证的资源的各种语言的实现:http://www.cnblogs.com/QLeelulu/archive/2009/11/22/1607898.html
-
理解OAuth 2.0:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
-
OAuth 2和JWT - 如何设计安全的API?:http://moakap.leanote.com/post/OAuth-2-vs.-JSON-Web-Token-JWT-如何设计安全的API?
-
Securing RESTful Web Services with OAuth2:https://content.pivotal.io/blog/securing-restful-web-services-with-oauth2
-
Server 端的认证——拥抱 JWT(一):https://juejin.im/entry/581c8e92bf22ec0068c0cbfc
-
JSON Web Token - 在Web应用间安全地传递信息:http://blog.leapoahead.com/2015/09/06/understanding-jwt/
-
八幅漫画理解使用JSON Web Token设计单点登录系统:http://blog.leapoahead.com/2015/09/07/user-authentication-with-jwt/
-
基于Token的WEB后台认证机制:http://www.cnblogs.com/xiekeli/p/5607107.html
-
什么是 JWT -- JSON WEB TOKEN:http://www.jianshu.com/p/576dbf44b2ae