.html', # zy: 成功页面 - OAuth绑定成功提示
+ views.bindsuccess, # zy: 视图函数 - 显示绑定成功信息
+ name='bindsuccess'), # zy: URL名称 - 绑定成功页面
path(
- r'oauth/oauthlogin',
- views.oauthlogin,
- name='oauthlogin')]
+ r'oauth/oauthlogin', # zy: 入口路径 - OAuth登录入口
+ views.oauthlogin, # zy: 入口视图 - 跳转到OAuth服务商授权页面
+ name='oauthlogin')] # zy: URL名称 - OAuth登录功能
diff --git a/src/django-master/oauth/views.py b/src/django-master/oauth/views.py
index 12e3a6e..22889a6 100644
--- a/src/django-master/oauth/views.py
+++ b/src/django-master/oauth/views.py
@@ -27,29 +27,29 @@ logger = logging.getLogger(__name__)
def get_redirecturl(request):
- nexturl = request.GET.get('next_url', None)
+ nexturl = request.GET.get('next_url', None) # zy: 获取重定向URL参数
if not nexturl or nexturl == '/login/' or nexturl == '/login':
- nexturl = '/'
+ nexturl = '/' # zy: 默认重定向到首页
return nexturl
- p = urlparse(nexturl)
+ p = urlparse(nexturl) # zy: 解析URL防止开放重定向攻击
if p.netloc:
site = get_current_site().domain
if not p.netloc.replace('www.', '') == site.replace('www.', ''):
- logger.info('非法url:' + nexturl)
+ logger.info('非法url:' + nexturl) # zy: 安全记录 - 记录非法URL
return "/"
return nexturl
def oauthlogin(request):
- type = request.GET.get('type', None)
+ type = request.GET.get('type', None) # zy: 获取OAuth类型参数
if not type:
return HttpResponseRedirect('/')
- manager = get_manager_by_type(type)
+ manager = get_manager_by_type(type) # zy: 关键调用 - 获取对应类型的OAuth管理器
if not manager:
return HttpResponseRedirect('/')
nexturl = get_redirecturl(request)
- authorizeurl = manager.get_authorization_url(nexturl)
- return HttpResponseRedirect(authorizeurl)
+ authorizeurl = manager.get_authorization_url(nexturl) # zy: 核心功能 - 生成授权URL
+ return HttpResponseRedirect(authorizeurl) # zy: 重定向到OAuth服务商授权页面
def authorize(request):
@@ -59,96 +59,96 @@ def authorize(request):
manager = get_manager_by_type(type)
if not manager:
return HttpResponseRedirect('/')
- code = request.GET.get('code', None)
+ code = request.GET.get('code', None) # zy: 关键参数 - OAuth服务商返回的授权码
try:
- rsp = manager.get_access_token_by_code(code)
+ rsp = manager.get_access_token_by_code(code) # zy: 核心调用 - 使用授权码获取访问令牌
except OAuthAccessTokenException as e:
- logger.warning("OAuthAccessTokenException:" + str(e))
+ logger.warning("OAuthAccessTokenException:" + str(e)) # zy: 重要日志 - 令牌获取异常
return HttpResponseRedirect('/')
except Exception as e:
logger.error(e)
rsp = None
nexturl = get_redirecturl(request)
if not rsp:
- return HttpResponseRedirect(manager.get_authorization_url(nexturl))
- user = manager.get_oauth_userinfo()
+ return HttpResponseRedirect(manager.get_authorization_url(nexturl)) # zy: 失败时重新授权
+ user = manager.get_oauth_userinfo() # zy: 关键调用 - 获取用户信息
if user:
if not user.nickname or not user.nickname.strip():
- user.nickname = "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S')
+ user.nickname = "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S') # zy: 生成默认昵称
try:
- temp = OAuthUser.objects.get(type=type, openid=user.openid)
+ temp = OAuthUser.objects.get(type=type, openid=user.openid) # zy: 检查是否已存在该OAuth用户
temp.picture = user.picture
temp.metadata = user.metadata
temp.nickname = user.nickname
- user = temp
+ user = temp # zy: 使用已存在的用户记录
except ObjectDoesNotExist:
pass
# facebook的token过长
if type == 'facebook':
- user.token = ''
- if user.email:
- with transaction.atomic():
+ user.token = '' # zy: 特殊处理 - Facebook令牌过长,清空存储
+ if user.email: # zy: 关键判断 - 用户有邮箱直接登录
+ with transaction.atomic(): # zy: 重要 - 数据库事务保证数据一致性
author = None
try:
- author = get_user_model().objects.get(id=user.author_id)
+ author = get_user_model().objects.get(id=user.author_id) # zy: 查找已关联的用户
except ObjectDoesNotExist:
pass
if not author:
- result = get_user_model().objects.get_or_create(email=user.email)
+ result = get_user_model().objects.get_or_create(email=user.email) # zy: 根据邮箱获取或创建用户
author = result[0]
- if result[1]:
+ if result[1]: # zy: 判断是否为新创建的用户
try:
get_user_model().objects.get(username=user.nickname)
except ObjectDoesNotExist:
- author.username = user.nickname
+ author.username = user.nickname # zy: 使用OAuth昵称作为用户名
else:
- author.username = "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S')
- author.source = 'authorize'
+ author.username = "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S') # zy: 昵称冲突时生成唯一用户名
+ author.source = 'authorize' # zy: 标记用户来源
author.save()
- user.author = author
+ user.author = author # zy: 关联OAuth用户到系统用户
user.save()
oauth_user_login_signal.send(
- sender=authorize.__class__, id=user.id)
- login(request, author)
+ sender=authorize.__class__, id=user.id) # zy: 重要 - 发送登录信号
+ login(request, author) # zy: 核心功能 - 登录用户
return HttpResponseRedirect(nexturl)
- else:
+ else: # zy: 用户没有邮箱,需要补充
user.save()
url = reverse('oauth:require_email', kwargs={
'oauthid': user.id
- })
+ }) # zy: 生成邮箱补充页面URL
- return HttpResponseRedirect(url)
+ return HttpResponseRedirect(url) # zy: 重定向到邮箱补充页面
else:
return HttpResponseRedirect(nexturl)
def emailconfirm(request, id, sign):
if not sign:
- return HttpResponseForbidden()
+ return HttpResponseForbidden() # zy: 安全拒绝 - 无签名参数
if not get_sha256(settings.SECRET_KEY +
str(id) +
- settings.SECRET_KEY).upper() == sign.upper():
+ settings.SECRET_KEY).upper() == sign.upper(): # zy: 重要 - 验证签名防止篡改
return HttpResponseForbidden()
oauthuser = get_object_or_404(OAuthUser, pk=id)
with transaction.atomic():
if oauthuser.author:
author = get_user_model().objects.get(pk=oauthuser.author_id)
else:
- result = get_user_model().objects.get_or_create(email=oauthuser.email)
+ result = get_user_model().objects.get_or_create(email=oauthuser.email) # zy: 创建系统用户
author = result[0]
if result[1]:
- author.source = 'emailconfirm'
+ author.source = 'emailconfirm' # zy: 标记来源为邮箱确认
author.username = oauthuser.nickname.strip() if oauthuser.nickname.strip(
- ) else "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S')
+ ) else "djangoblog" + timezone.now().strftime('%y%m%d%I%M%S') # zy: 设置用户名
author.save()
- oauthuser.author = author
+ oauthuser.author = author # zy: 完成关联
oauthuser.save()
oauth_user_login_signal.send(
sender=emailconfirm.__class__,
- id=oauthuser.id)
- login(request, author)
+ id=oauthuser.id) # zy: 发送登录信号
+ login(request, author) # zy: 登录用户
site = 'http://' + get_current_site().domain
content = _('''
@@ -162,22 +162,22 @@ def emailconfirm(request, id, sign):
%(site)s
''') % {'oauthuser_type': oauthuser.type, 'site': site}
- send_email(emailto=[oauthuser.email, ], title=_('Congratulations on your successful binding!'), content=content)
+ send_email(emailto=[oauthuser.email, ], title=_('Congratulations on your successful binding!'), content=content) # zy: 发送绑定成功邮件
url = reverse('oauth:bindsuccess', kwargs={
'oauthid': id
})
url = url + '?type=success'
- return HttpResponseRedirect(url)
+ return HttpResponseRedirect(url) # zy: 重定向到成功页面
class RequireEmailView(FormView):
- form_class = RequireEmailForm
- template_name = 'oauth/require_email.html'
+ form_class = RequireEmailForm # zy: 使用邮箱表单类
+ template_name = 'oauth/require_email.html' # zy: 模板路径
def get(self, request, *args, **kwargs):
- oauthid = self.kwargs['oauthid']
+ oauthid = self.kwargs['oauthid'] # zy: 获取URL参数中的OAuth用户ID
oauthuser = get_object_or_404(OAuthUser, pk=oauthid)
- if oauthuser.email:
+ if oauthuser.email: # zy: 安全检查 - 如果已有邮箱直接跳过
pass
# return HttpResponseRedirect('/')
@@ -187,32 +187,32 @@ class RequireEmailView(FormView):
oauthid = self.kwargs['oauthid']
return {
'email': '',
- 'oauthid': oauthid
+ 'oauthid': oauthid # zy: 初始化表单数据
}
def get_context_data(self, **kwargs):
oauthid = self.kwargs['oauthid']
oauthuser = get_object_or_404(OAuthUser, pk=oauthid)
if oauthuser.picture:
- kwargs['picture'] = oauthuser.picture
+ kwargs['picture'] = oauthuser.picture # zy: 传递用户头像到模板
return super(RequireEmailView, self).get_context_data(**kwargs)
def form_valid(self, form):
- email = form.cleaned_data['email']
+ email = form.cleaned_data['email'] # zy: 获取验证后的邮箱
oauthid = form.cleaned_data['oauthid']
oauthuser = get_object_or_404(OAuthUser, pk=oauthid)
- oauthuser.email = email
+ oauthuser.email = email # zy: 保存邮箱到OAuth用户
oauthuser.save()
sign = get_sha256(settings.SECRET_KEY +
- str(oauthuser.id) + settings.SECRET_KEY)
+ str(oauthuser.id) + settings.SECRET_KEY) # zy: 生成邮箱确认签名
site = get_current_site().domain
if settings.DEBUG:
- site = '127.0.0.1:8000'
+ site = '127.0.0.1:8000' # zy: 开发环境域名
path = reverse('oauth:email_confirm', kwargs={
'id': oauthid,
'sign': sign
})
- url = "http://{site}{path}".format(site=site, path=path)
+ url = "http://{site}{path}".format(site=site, path=path) # zy: 生成完整的确认链接
content = _("""
Please click the link below to bind your email
@@ -225,29 +225,29 @@ class RequireEmailView(FormView):
%(url)s
""") % {'url': url}
- send_email(emailto=[email, ], title=_('Bind your email'), content=content)
+ send_email(emailto=[email, ], title=_('Bind your email'), content=content) # zy: 发送邮箱确认邮件
url = reverse('oauth:bindsuccess', kwargs={
'oauthid': oauthid
})
- url = url + '?type=email'
- return HttpResponseRedirect(url)
+ url = url + '?type=email' # zy: 添加类型参数
+ return HttpResponseRedirect(url) # zy: 重定向到绑定成功页面
def bindsuccess(request, oauthid):
- type = request.GET.get('type', None)
+ type = request.GET.get('type', None) # zy: 获取成功类型
oauthuser = get_object_or_404(OAuthUser, pk=oauthid)
if type == 'email':
title = _('Bind your email')
content = _(
'Congratulations, the binding is just one step away. '
- 'Please log in to your email to check the email to complete the binding. Thank you.')
+ 'Please log in to your email to check the email to complete the binding. Thank you.') # zy: 等待邮箱确认提示
else:
title = _('Binding successful')
content = _(
"Congratulations, you have successfully bound your email address. You can use %(oauthuser_type)s"
" to directly log in to this website without a password. You are welcome to continue to follow this site." % {
- 'oauthuser_type': oauthuser.type})
+ 'oauthuser_type': oauthuser.type}) # zy: 绑定成功提示
return render(request, 'oauth/bindsuccess.html', {
'title': title,
- 'content': content
- })
+ 'content': content # zy: 渲染成功页面
+ })
\ No newline at end of file