django 用户认证之二:token的原理和用法

基于restframework 的用户验证跟 django 用户验证的区别 :

django 用户验证只要是基于 cookie 与 session 来完成的。

 

我现在访问我的 restf api 接口时可以看到浏览器会有一个登陆 ,这里通过 django 创建的 超级用户

或者注册的用户就可以登陆

 

 

 

这是因为我们在 django 的url 中配置了

url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),

而 对应的 rest_framework.urls 有 包含 login 和 logout 两个url。

 

这里会让登陆验证变得很简单,但是 他会验证 csrf ,我们登陆时 django 返回的 html 中其实是

包含一个 csrf 的 code 的,用来做表单的 安全验证的。

所以

如果用户验证需要做成 restful api ,这个 自带的 login是无法拿来直接用的。

 

那如果我们需要做成一个前后端分离的用户验证, 就需要通过其他的方法。 【Auth 模块】

 

django 的 MIDDLEWARE 中包含的以下两个 MIDDLEWARE

'django.contrib.sessions.middleware.SessionMiddleware',

'django.contrib.auth.middleware.AuthenticationMiddleware',

可以在一个 request 进来的时候,将request里的 cookie 里面的 session_id 转换成

我们的 user !!!!! 也就是我们之前看到的 request.user 。

 

我们现在需要配置 restful 的 MIDDLEWARE , 直接在 django 的 settings.py 里面添加

 

REST_FRAMEWORK = {

'DEFAULT_AUTHENTICATION_CLASSES': (

'rest_framework.authentication.BasicAuthentication',

'rest_framework.authentication.SessionAuthentication',

)

}

官方文档显示 restful 提供的 auth 有三种 :

BasicAuthenticationTokenAuthenticationSessionAuthentication

其中 :

SessionAuthentication :跟django中的机制是一样的, 常用于浏览器,

因为浏览器会自动设置 cookie ,并将他的 cooike 和session 带到服务器,

所以前后端分离的系统用这种机制比较少见,但是还是可以做。

TokenAuthentication : 是需要重点关注的,使用他前 ,必须先将 'rest_framework.authtoken'

添加到 django 的 INSTALLED_APPS 中。

INSTALLED_APPS = ( ... 'rest_framework.authtoken' )

这个 tokenauth 实际上会给我们创建一张表,凡是有表的 app 都要加入到 INSTALLED_APPS 中。

如果不加人,就不会帮我们生成这些表。

此时执行 migrate 进行数据迁移。

可以看到为我们生成了一张表,该表有一个外键指向我们的 UserProfile (用户信息)表。

 

一个用户对于一个 token 。

而我创建一个超级用户的时候,并没有在 authtoken_token 这张表里面给我添加一个对应的 token 。

这个 token 需要我们自己来创建 。创建方法如下 ,调用 Token 模块,将 user 传进去:

 

from rest_framework.authtoken.models import Token token = Token.objects.create(user=...) print token.key

 

所以 当用户注册时保存了提交的 UserProfile 之后,调用这段代码,把保存的 UserProfile 传进去。

这样就会生成 token 。

 

---------------------------------

 

而后端需要在 django 的 url 中配置 token 的url :

from rest_framework.authtoken import views urlpatterns += [ url(r'^api-token-auth/', views.obtain_auth_token) ]

现在可以通过向 http://127.0.0.1:8000/api-token-auth/ 这个url 发送 post 请求并且携带

{

"username":"admin",

"password":"admin123456"

}

这个方式来获取 token ,发送请求后,他会返回一个 token 。此时如果这个 UserProfile

没有对应的 key ,就会在 authtoken_token 这张表创建一条数据 ,并且关联到你提交的

用户 ,给他生成一个 key 。

 

 

前端如何使用这个 token ? 【把他放到 http 的 header 里面】

对于客户端进行身份验证,令牌密钥应该包含在AuthorizationHTTP头中。关键字应以字符串文字“Token”为前缀,用空格分隔两个字符串。例如:

Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

 

此时我在我的 url 请求的头部添加这个之后,访问我的 restful api 资源了后台获取到这个 token 后

还不能解析出这个 token 对应的用户是谁,我们需要在 REST_FRAMEWORK 里添加

'rest_framework.authentication.TokenAuthentication',

才能解析出对应的用户 。

REST_FRAMEWORK = {

'DEFAULT_AUTHENTICATION_CLASSES': (

'rest_framework.authentication.BasicAuthentication',

'rest_framework.authentication.SessionAuthentication',

'rest_framework.authentication.TokenAuthentication',

)

}

此时需要知道用户传递过来的 token 是什么 ,直接通过 request.auth 就可以看到。

完成 上面两步,就可以访问我的 restful api 资源了。

(以前需要登录,现在只要头部包含 这个 token 就可以访问。)

 

如果用户在 token 过期的情况下访问公共url , 就会报错, 这个问题前端也可以解决,后端的解决方案是, 把这个 token 验证不放在 settings.py 里做全局验证, 只对部分接口做验证。

把 REST_FRAMEWORK 中下面这个

1. 'rest_framework.authentication.TokenAuthentication',

注释掉 ,

2.在需要做验证的视图那里 导入

from rest_framework.authentication import TokenAuthentication

然后在视图里添加 authentication_classes 属性。 因为要给他个元组, 所以记得用逗号

authentication_classes = (TokenAuthentication, )

 

 

这个 token 的缺点是 :

1.这个token 是保存在服务器里面的。

如果我们是一个分布式系统,有两套子系统想要使用同一个认证系统,他就会出现问题,

因为他的 token 是放在某一台服务器的,如果是分布式的,那我们还得将这些用户同步过去。

2.这个 toen 是没有过期时间的,永久有效,一旦泄露了别人就可以一直用。

 

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值