- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章详解django.contirb.auth-认证由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
首先看middleware的定义:
auth模块有两个middleware:AuthenticationMiddleware和SessionAuthenticationMiddleware.
AuthenticationMiddleware负责向request添加user属性 。
1
2
3
4
5
6
7
8
9
|
class
AuthenticationMiddleware(
object
):
def
process_request(
self
, request):
assert
hasattr
(request,
'session'
), (
"The Django authentication middleware requires session middleware "
"to be installed. Edit your MIDDLEWARE_CLASSES setting to insert "
"'django.contrib.sessions.middleware.SessionMiddleware' before "
"'django.contrib.auth.middleware.AuthenticationMiddleware'."
)
request.user
=
SimpleLazyObject(
lambda
: get_user(request))
|
可以看见AuthenticationMiddleware首先检查是否由session属性,因为它需要session存储用户信息.
user属性的添加,被延迟到了get_user()函数里。SimpleLazyObject是一种延迟的技术.
在来看SessionAuthenticationMiddleware的定义:
它负责session验证 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
class
SessionAuthenticationMiddleware(
object
):
"""
Middleware for invalidating a user's sessions that don't correspond to the
user's current session authentication hash (generated based on the user's
password for AbstractUser).
"""
def
process_request(
self
, request):
user
=
request.user
if
user
and
hasattr
(user,
'get_session_auth_hash'
):
session_hash
=
request.session.get(auth.HASH_SESSION_KEY)
session_hash_verified
=
session_hash
and
constant_time_compare(
session_hash,
user.get_session_auth_hash()
)
if
not
session_hash_verified:
auth.logout(request)
|
通过比较user的get_session_auth_hash方法,和session里面的auth.HASH_SESSION_KEY属性,判断用户的session是否正确.
至于request里面的user对象,由有什么属性,需要看看get_user()函数的定义.
1
2
3
4
|
def
get_user(request):
if
not
hasattr
(request,
'_cached_user'
):
request._cached_user
=
auth.get_user(request)
return
request._cached_user
|
显然get_user方法在request增加了_cached_user属性,用来作为缓存.
因为用户认证需要查询数据库,得到用户的信息,所以减少开销是有必要的.
注意,这种缓存只针对同一个request而言的,即在一个view中多次访问request.user属性.
每次http请求都是新的request.
再接着看auth.get_user()方法的定义,深入了解request.user这个对象:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
def
get_user(request):
"""
Returns the user model instance associated with the given request session.
If no user is retrieved an instance of `AnonymousUser` is returned.
"""
from
.models
import
AnonymousUser
user
=
None
try
:
user_id
=
request.session[SESSION_KEY]
backend_path
=
request.session[BACKEND_SESSION_KEY]
except
KeyError:
pass
else
:
if
backend_path
in
settings.AUTHENTICATION_BACKENDS:
backend
=
load_backend(backend_path)
user
=
backend.get_user(user_id)
return
user
or
AnonymousUser()
|
首先它会假设客户端和服务器已经建立session机制了,这个session中的SESSION_KEY属性,就是user的id号.
这个session的BACKEND_SESSION_KEY属性,就是指定使用哪种后台技术获取用户信息。最后使用backend.get_user()获取到user。如果不满足,就返回AnonymousUser对象.
从这个获取user的过程,首先有个前提,就是客户端与服务端得先建立session机制。那么这个session机制是怎么建立的呢?
这个session建立的过程在auth.login函数里:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
def
login(request, user):
"""
Persist a user id and a backend in the request. This way a user doesn't
have to reauthenticate on every request. Note that data set during
the anonymous session is retained when the user logs in.
"""
session_auth_hash
=
''
if
user
is
None
:
user
=
request.user
if
hasattr
(user,
'get_session_auth_hash'
):
session_auth_hash
=
user.get_session_auth_hash()
if
SESSION_KEY
in
request.session:
if
request.session[SESSION_KEY] !
=
user.pk
or
(
session_auth_hash
and
request.session.get(HASH_SESSION_KEY) !
=
session_auth_hash):
# To avoid reusing another user's session, create a new, empty
# session if the existing session corresponds to a different
# authenticated user.
request.session.flush()
else
:
request.session.cycle_key()
request.session[SESSION_KEY]
=
user.pk
request.session[BACKEND_SESSION_KEY]
=
user.backend
request.session[HASH_SESSION_KEY]
=
session_auth_hash
if
hasattr
(request,
'user'
):
request.user
=
user
rotate_token(request)
|
首先它会判断是否存在与用户认证相关的session,如果有就清空数据,如果没有就新建.
然后再写如session的值:SESSION_KEY, BACKEND_SESSION_KEY, HASH_SESSION_KEY.
然后讲一下登录时,使用auth通常的做法:
1
2
3
4
5
6
7
8
9
|
from
django.contrib.auth
import
authenticate, login
def
login_view(request):
username
=
request.POST[
'username'
]
password
=
request.POST[
'password'
]
user
=
authenticate(username
=
username, password
=
password)
if
user
is
not
None
:
login(request, user)
# 转到成功页面
else
:
# 返回错误信息
|
一般提交通过POST方式提交,然后调用authenticate方法验证,成功后使用login创建session.
继续看看authenticate的定义:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
def
authenticate(
*
*
credentials):
"""
If the given credentials are valid, return a User object.
"""
for
backend
in
get_backends():
try
:
inspect.getcallargs(backend.authenticate,
*
*
credentials)
except
TypeError:
# This backend doesn't accept these credentials as arguments. Try the next one.
continue
try
:
user
=
backend.authenticate(
*
*
credentials)
except
PermissionDenied:
# This backend says to stop in our tracks - this user should not be allowed in at all.
return
None
if
user
is
None
:
continue
# Annotate the user object with the path of the backend.
user.backend
=
"%s.%s"
%
(backend.__module__, backend.__class__.__name__)
return
user
# The credentials supplied are invalid to all backends, fire signal
user_login_failed.send(sender
=
__name__,
credentials
=
_clean_credentials(credentials))
|
它会去轮询backends,通过调用backend的authenticate方法认证.
注意它在后面更新了user的backend属性,表明此用户是使用哪种backend认证方式。它的值会在login函数里,被存放在session的BACKEND_SESSION_KEY属性里.
通过backend的authenticate方法返回的user,是没有这个属性的.
最后说下登录以后auth的用法。上面展示了登录时auth的用法,在登录以后,就会建立session机制。所以直接获取request的user属性,就可以判断用户的信息和状态.
1
2
3
4
5
|
def
my_view(request):
if
request.user.is_authenticated():
# 认证的用户
else
:
# 匿名用户
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://my.oschina.net/u/569730/blog/369144 。
最后此篇关于详解django.contirb.auth-认证的文章就讲到这里了,如果你想了解更多关于详解django.contirb.auth-认证的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在使用 Tornado 与 twitter 等第三方进行身份验证。 我的登录处理程序看起来像这样 class AuthLoginHandler(BaseHandler, tornado.auth.
有没有一种真正的方法可以在 Pylons 中添加身份验证?我见过很多不同的方法,但大多数方法要么过时,要么过于复杂。是否有教程可以解释如何以良好而可靠的方式添加身份验证? 最佳答案 考虑使用 repo
RESTful 身份验证是什么意思,它是如何工作的?我在谷歌上找不到很好的概述。我唯一的理解是您在 URL 中传递了 session key (记住),但这可能是非常错误的。 最佳答案 如何在 RES
我正在考虑在基于插件的系统中实现安全性的多种方式。现在,当我说“安全”时,我的意思是: a) 插件系统的开发人员如何确保插件在核心平台上的使用是安全的。b) 插件开发人员如何确保在其平台上使用的插件是
我正在使用 WCF Webhttp 服务。我创建了一堆服务,剩下的就是放入用户身份验证... 问题 与其余架构风格保持一致,我是否应该针对用户 db 验证每个服务调用。 如果是这样,我应该在每次调用服
假设我想对 Mifare Classic 进行身份验证。 我如何知道要发送到卡的确切类型的 APDU? 例子。 这段代码: bcla = 0xFF; bins = 0x86; bp1 = 0x0;
我通过在文件 xyz.php 中编写以下代码登录到网站。当我运行这个文件时,我会登录到 moodle 网站。有什么方法可以像下面的登录代码一样注销吗? $user = authenticate_use
我有一个应用程序可以匿名访问除几个之外的所有 xpages。我需要强制用户登录这些 xpages。是使用 beforepageload 事件来检查用户登录页面并将其重定向到正确的方式还是有更好的方法?
我想用 ember.js 实现身份验证。 因此,当应用程序启动时,在路由器处理请求的 url 之前,我想检查用户状态。如果用户未通过身份验证,我想保存请求的 url 并重定向到特定的 url (/lo
您如何执行 jQuery Ajax 调用并在发送请求之前对调用进行身份验证? 我还没有登录所以必须进行身份验证。安全不是任何人都可以访问的问题,只需要进行身份验证。它只是基本的 http 身份验证,您
我尝试使用找到的 swift 代码 here在网站上找到here ,但响应是带有两个错误的 html 代码:“您必须输入密码!”和“您必须输入用户名!”我是 NSURLSession 的新手,并尝试更
我正在尝试连接到 Visa Direct API,但我没有通过基本的 SSL 证书认证,这是我的代码: import requests headers = { 'Content
我正在用 tornado 在 python 中开发一个 REST API,我将实现身份验证和授权,试图避免锁定到其他大项目,即 django。我也在通过论坛和 SO 环顾四周,我喜欢一个可能适合的解决
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭10
如何在 Android 中通过 HTTP 进行身份验证? 最佳答案 我非常难以在 Android 中通过 HTTP 进行身份验证,因为在浏览器(Web 和 Android native )中它工作完美
我有一些关于登录和 session 的问题。我有这段代码: 数据库查询: login: function(req,callback) { var query = 'SELECT id FROM
我开始使用 Swift 开发 iOS 应用。现在我正处于需要创建登录系统的部分。但是,我们需要人们提供的 LinkedIn 信息。 我如何在 iOS 中使用 OAuth2 API 来实现这一点? 我已
如果没有找到用户,问题出在每个 $routeChangeStart 上,如果我只输入 url,它仍然会引导我访问页面。 现在我已经在服务器上重写了规则。 Options +FollowSymlinks
简单代码 require 'net/http' url = URI.parse('get json/other data here [link]') req = Net::HTTP::Get.new(
参考文档: https://docs.sonarqube.org/latest/instance-administration/security/ 概述 SonarQube具有
我是一名优秀的程序员,十分优秀!