securing the video page with auth.guard
This commit is contained in:
parent
69407e9f53
commit
876317a994
7 changed files with 87 additions and 9 deletions
|
|
@ -1,7 +1,8 @@
|
||||||
from rest_framework.views import APIView
|
from rest_framework.views import APIView
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework import status
|
from rest_framework import status, authentication
|
||||||
from rest_framework.authtoken.models import Token
|
from rest_framework.authtoken.models import Token
|
||||||
|
from rest_framework.authtoken.views import ObtainAuthToken
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import authenticate
|
||||||
from .serializer import LoginSerializer
|
from .serializer import LoginSerializer
|
||||||
from users.serializer import UserSerializer
|
from users.serializer import UserSerializer
|
||||||
|
|
@ -32,7 +33,7 @@ class LoginView(APIView):
|
||||||
|
|
||||||
def _create_token_response(self, user):
|
def _create_token_response(self, user):
|
||||||
token, created = Token.objects.get_or_create(user=user)
|
token, created = Token.objects.get_or_create(user=user)
|
||||||
return Response({'token': token.key}, status=status.HTTP_200_OK)
|
return Response({token.key}, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
class RegisterView(APIView):
|
class RegisterView(APIView):
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
|
|
@ -87,3 +88,11 @@ class VerifyEmailView(APIView):
|
||||||
return Response(status=status.HTTP_200_OK)
|
return Response(status=status.HTTP_200_OK)
|
||||||
else:
|
else:
|
||||||
return Response({"error": "Invalid email or token."}, status=status.HTTP_400_BAD_REQUEST)
|
return Response({"error": "Invalid email or token."}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
class AuthView(ObtainAuthToken):
|
||||||
|
authentication_classes = [authentication.TokenAuthentication]
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
return Response(request.user.id, status=status.HTTP_200_OK)
|
||||||
|
return Response({"error": "User is not logged in"}, status=status.HTTP_401_UNAUTHORIZED)
|
||||||
|
|
@ -17,12 +17,13 @@ Including another URLconf
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
from users import views
|
from users import views
|
||||||
from auth.views import LoginView, RegisterView, VerifyEmailView
|
from auth.views import LoginView, RegisterView, VerifyEmailView, AuthView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('users/', views.user_list),
|
path('users/', views.user_list),
|
||||||
path('users/<int:id>/', views.user_detail),
|
path('users/<int:id>/', views.user_detail),
|
||||||
|
path('auth/', AuthView.as_view()),
|
||||||
path('auth/login/', LoginView.as_view()),
|
path('auth/login/', LoginView.as_view()),
|
||||||
path('auth/register/', RegisterView.as_view()),
|
path('auth/register/', RegisterView.as_view()),
|
||||||
path('auth/verify-email/', VerifyEmailView.as_view()),
|
path('auth/verify-email/', VerifyEmailView.as_view()),
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { HomeComponent } from './components/home/home.component';
|
||||||
import { ImprintComponent } from './shared/components/legal-information/imprint/imprint.component';
|
import { ImprintComponent } from './shared/components/legal-information/imprint/imprint.component';
|
||||||
import { PrivacyPolicyComponent } from './shared/components/legal-information/privacy-policy/privacy-policy.component';
|
import { PrivacyPolicyComponent } from './shared/components/legal-information/privacy-policy/privacy-policy.component';
|
||||||
import { BrowseComponent } from './components/home/browse/browse.component';
|
import { BrowseComponent } from './components/home/browse/browse.component';
|
||||||
|
import { AuthGuard } from './auth.guard';
|
||||||
|
|
||||||
export const routes: Routes = [
|
export const routes: Routes = [
|
||||||
{ path: '', component: HomeComponent },
|
{ path: '', component: HomeComponent },
|
||||||
|
|
@ -12,5 +13,5 @@ export const routes: Routes = [
|
||||||
{ path: 'verify-email', component: HomeComponent },
|
{ path: 'verify-email', component: HomeComponent },
|
||||||
{ path: 'imprint', component: ImprintComponent },
|
{ path: 'imprint', component: ImprintComponent },
|
||||||
{ path: 'privacy-policy', component: PrivacyPolicyComponent },
|
{ path: 'privacy-policy', component: PrivacyPolicyComponent },
|
||||||
{ path: 'browse', component: BrowseComponent },
|
{ path: 'browse', component: BrowseComponent, canActivate: [AuthGuard] },
|
||||||
];
|
];
|
||||||
|
|
|
||||||
17
frontend/src/app/auth.guard.spec.ts
Normal file
17
frontend/src/app/auth.guard.spec.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
import { CanActivateFn } from '@angular/router';
|
||||||
|
|
||||||
|
import { authGuard } from './auth.guard';
|
||||||
|
|
||||||
|
describe('authGuard', () => {
|
||||||
|
const executeGuard: CanActivateFn = (...guardParameters) =>
|
||||||
|
TestBed.runInInjectionContext(() => authGuard(...guardParameters));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
expect(executeGuard).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
29
frontend/src/app/auth.guard.ts
Normal file
29
frontend/src/app/auth.guard.ts
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
import { Observable, of } from 'rxjs';
|
||||||
|
import { map, catchError } from 'rxjs/operators';
|
||||||
|
import { AuthService } from './services/auth.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root',
|
||||||
|
})
|
||||||
|
export class AuthGuard {
|
||||||
|
constructor(private authService: AuthService, private router: Router) {}
|
||||||
|
|
||||||
|
canActivate(): Observable<boolean> | Promise<boolean> | boolean {
|
||||||
|
return this.authService.checkAuthUser().pipe(
|
||||||
|
map((isAuthenticated) => {
|
||||||
|
if (isAuthenticated) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
this.router.navigate(['/']);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
catchError(() => {
|
||||||
|
this.router.navigate(['/']);
|
||||||
|
return of(false);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
|
||||||
import { HeaderComponent } from '../../../shared/components/header/header.component';
|
import { HeaderComponent } from '../../../shared/components/header/header.component';
|
||||||
import { HeroBannerComponent } from './hero-banner/hero-banner.component';
|
import { HeroBannerComponent } from './hero-banner/hero-banner.component';
|
||||||
import { CategoriesComponent } from './categories/categories.component';
|
import { CategoriesComponent } from './categories/categories.component';
|
||||||
|
import { AuthService } from '../../../services/auth.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-browse',
|
selector: 'app-browse',
|
||||||
|
|
@ -34,6 +35,8 @@ export class BrowseComponent implements OnInit {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
constructor(private authService: AuthService) {}
|
||||||
|
|
||||||
currentMovie: any[] = [];
|
currentMovie: any[] = [];
|
||||||
playMovie: string = '';
|
playMovie: string = '';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { lastValueFrom } from 'rxjs';
|
import { catchError, lastValueFrom, map, Observable, of } from 'rxjs';
|
||||||
import { environment } from '../environments/environment.development';
|
import { environment } from '../environments/environment.development';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
|
|
@ -11,6 +11,12 @@ export class AuthService {
|
||||||
|
|
||||||
constructor(private http: HttpClient) {}
|
constructor(private http: HttpClient) {}
|
||||||
|
|
||||||
|
async register(body: any) {
|
||||||
|
await lastValueFrom(
|
||||||
|
this.http.post(`${environment.baseUrl}/auth/register/`, body)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async login(body: any, storage: boolean) {
|
async login(body: any, storage: boolean) {
|
||||||
const data = await lastValueFrom(
|
const data = await lastValueFrom(
|
||||||
this.http.post(`${environment.baseUrl}/auth/login/`, body)
|
this.http.post(`${environment.baseUrl}/auth/login/`, body)
|
||||||
|
|
@ -30,9 +36,21 @@ export class AuthService {
|
||||||
: sessionStorage.setItem('authToken', data.toString());
|
: sessionStorage.setItem('authToken', data.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
async register(body: any) {
|
checkAuthUser(): Observable<boolean> {
|
||||||
await lastValueFrom(
|
const headers = this.getAuthHeaders();
|
||||||
this.http.post(`${environment.baseUrl}/auth/register/`, body)
|
return this.http.get<any>(`${environment.baseUrl}/auth/`, { headers }).pipe(
|
||||||
|
map((response) => true),
|
||||||
|
catchError(() => of(false))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getAuthHeaders(): HttpHeaders {
|
||||||
|
let authToken = localStorage.getItem('authToken');
|
||||||
|
if (!authToken) {
|
||||||
|
authToken = sessionStorage.getItem('authToken');
|
||||||
|
}
|
||||||
|
return new HttpHeaders({
|
||||||
|
Authorization: `Token ${authToken}`, // Ensure this matches your backend
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue