Привязка логина и api моего профиля в шаблоне django
это мой вид login api. я использую adminlte для frontend для разработки панели администратора
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 возвращает анонимного пользователя, когда пользователь успешно вошел в систему. не ошибаюсь ли я, создавая login api??
предложите, как получить пользователя и его id или предложите другой способ сделать то же самое.
Django's 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
Добавьте это промежуточное ПО к параметру MIDDLEWARE в файле настроек Django. Это просто быстрый пример, который может не охватывать все случаи.