这是我的登录 api 视图。我正在使用 adminlte 作为前端来开发管理面板
class LoginView(APIView):
@extend_schema(request={'email', 'password'})
def post(self, request):
email = request.data.get('email')
password = request.data.get('password')
remember_me = request.data.get('remember_me')
user = authenticate(email=email, password=password)
if user:
# Set the token expiration based on remember_me option
if remember_me:
token_lifetime = timezone.now() + timezone.timedelta(days=30) # Long-lived token
else:
token_lifetime = timezone.now() + timezone.timedelta(minutes=24) # Short-lived token
# Generate or retrieve token for the authenticated user
token, _ = Token.objects.get_or_create(user=user)
token.created = timezone.now()
token.expires = token_lifetime
user.token = token.key
user.last_login = timezone.now()
user.save(update_fields=['token', 'last_login'])
token.save()
return Response({ 'success': True, 'user_id': user.id, 'email': user.email, 'token': token.key}, status=status.HTTP_200_OK)
else:
return Response({ 'success': False, 'error': 'Invalid credentials'}, status=status.HTTP_401_UNAUTHORIZED)
这是我在 django 中的前端视图。
def login_view(request):
if request.method == 'POST':
data = {
'email': request.POST['email'],
'password': request.POST['password']
}
csrf_token = request.COOKIES.get('csrftoken')
headers = {'X-CSRFToken': csrf_token}
response_content, status_code = Http.post(request, f"{settings.API_URL_V1}/login", data=data, headers=headers)
if status_code == 200:
token = response_content.get('token')
if token:
request.session['token'] = token
messages.success(request, 'Logged in successfully')
return redirect('dashboard')
else:
if not data['email'] and not data['password']:
messages.error(request, 'Email and Password cannot be Empty!')
elif not 'password' or len('password') < 8 or not re.search("[!@#$%^&*()-_=+{};:,<.>]", 'password') or not re.search("[0-9]", 'password'):
messages.error(request, 'Password must be at least 8 characters long and contain at least one special symbol and one number.')
return render(request, 'login.html')
这是我的仪表板.html
{% extends 'adminlte/base.html' %}
{% block title %}Home{% endblock %}
{% block nav_header %}
{% include 'header.html' %}
{% endblock %}
{% block nav_sidebar %}
{% include 'sidebar.html' %}
{% endblock %}
{% block content %}
Add content
{% endblock %}
{% block nav_footer %}
{% include 'footer.html' %}
{% endblock %}
这是我的 header.html
{% block nav_header %}
<nav class="main-header navbar navbar-expand navbar-white navbar-light">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" data-widget="pushmenu" href="#"><i class="fas fa-bars"></i></a>
</li>
<li class="nav-item d-none d-sm-inline-block">
<a href="#" class="nav-link">About-us</a>
</li>
<li class="nav-item d-none d-sm-inline-block">
<a href="#" class="nav-link">Contact-us</a>
</li>
</ul>
<form class="form-inline ml-3">
<div class="input-group input-group-sm">
<input class="form-control form-control-navbar" type="search" placeholder="Search" aria-label="Search">
<div class="input-group-append">
<button class="btn btn-navbar" type="submit">
<i class="fas fa-search"></i>
</button>
</div>
</div>
</form>
<ul class="navbar-nav ml-auto">
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#">
{% if data.profile_image %}
<img src="{{ data.profile_image }}" class="avatar img-circle" alt="My Profile">
{% else %}
<i class="fas fa-user"></i>
{% endif %}
</a>
<div class="dropdown-menu dropdown-menu-lg dropdown-menu-right">
<div class="user-header bg-primary image">
{% if data.profile_image %}
<img src="{{ data.profile_image }}" class="img-circle" alt="{{ data.name }}">
{% else %}
<i class="fas fa-user-circle fa-5x"></i>
{% endif %}
</div>
<div class="dropdown-divider"></div>
<a href="{% url 'my_profile' request.user.id %}" class="dropdown-item">
<i class="fas fa-lock mr-2"></i> My Profile
</a>
<a href="{% url 'reset_password' %}" class="dropdown-item">
<i class="fas fa-lock mr-2"></i> Change Password
</a>
<div class="dropdown-divider"></div>
<a href="{% url 'signin' %}" class="dropdown-item dropdown-footer">Logout</a>
</div>
</li>
</ul>
</nav>
{% endblock %}
在此,url
<a href="{% url 'my_profile' request.user.id %}" class="dropdown-item"><i class="fas fa-lock mr-2"></i> My Profile</a>
为什么当用户登录成功时 request.user 返回匿名用户。我创建登录 api 是不是错了??
请建议如何获取用户和用户 ID,或建议另一种方法来执行此操作。
Django 的 request.user 不知道通过 API 完成的用户身份验证。 request.user 对象由 Django 的身份验证中间件使用 Django 的会话框架填充,该框架未在基于 API 的身份验证中使用。
在您的 API 中,您使用基于令牌的身份验证并在成功登录后将令牌存储在会话中。但是,Django 的身份验证中间件无法识别此令牌,并且 request.user 是匿名用户。
您可以使用 Django 的内置身份验证:如果您在管理面板中使用 Django 的模板和视图,则可以使用 Django 的内置身份验证系统,该系统与 request.user 配合良好。
或者编写一个自定义中间件来检查会话中的令牌,获取与令牌关联的用户,并设置 request.user。
from django.contrib.auth.middleware import MiddlewareMixin
from rest_framework.authtoken.models import Token
class TokenAuthMiddleware(MiddlewareMixin):
def process_request(self, request):
token_key = request.session.get('token')
if token_key:
try:
token = Token.objects.get(key=token_key)
request.user = token.user
except Token.DoesNotExist:
pass
将此中间件添加到 Django 设置文件中的 MIDDLEWARE 设置中。这只是一个简单的示例,可能无法涵盖所有情况。