Angular 2的Django会话身份验证 [英] Django session authentication with Angular 2
问题描述
我一直在到处寻找Angular 2的基于会话的身份验证.
I've been looking all around for session based authentication with Angular 2.
我正在构建一个在后端具有Django,在前端具有Angular 2的应用程序.为了简化过程,我尝试实现Django会话身份验证.
I'm building an application that has Django on backend and Angular 2 on the frontend. To keep the process simple I'm trying to implement Django session authentication.
// Angular 2 authentication service
import { Injectable } from "@angular/core";
import { Headers, Http, Response } from "@angular/http";
import "rxjs/add/operator/toPromise";
import 'rxjs/add/operator/map'
import { AppSettings } from "../../app.settings";
@Injectable()
export class UserAuthService {
private headers = new Headers({'Content-Type': 'application/json'});
private loginUrl = `${AppSettings.BACKEND_URL}` + '/api/v1/users/login/';
constructor(
private http: Http
) { }
login(username, password) {
let data = {
username: username,
password: password
};
return this.http.post(this.loginUrl, data, this.headers)
.map((response: Response) => response.json());
}
}
# Django Login view
def login(self, request):
username = request.data['username']
password = request.data['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
serializer = self.serializer_class(user)
return Response(serializer.data, status=status.HTTP_200_OK)
raise AuthenticationFailed
我成功调用了后端API,并且我的login
视图返回了成功的响应.
I'm successfully calling backend API and my login
view returns the successful response.
request.user
也将在登录后更新,但是当我尝试使用Angular调用其他API或直接浏览Django rest API时,该用户尚未登录.
Also request.user
gets updated after the login but when I try to call the other APIs using Angular or directly browse Django rest API user is not logged in.
推荐答案
此问题的答案是将CSRF令牌附加到X-CSRF标头中,因为django使用X-CSRF令牌标头来验证会话.
The answer to this question is to append CSRF token to the X-CSRF header, because django uses X-CSRF token header to verify the sessions.
我不完全记得我在哪里看到的,但是通过使用 angular2-cookie 并编写这样的自定义请求选项服务
I don't exactly remember where I saw this but Iachieved this by using angular2-cookie and writing a custom request options service like this
// Custom request options service
import { CookieService } from "angular2-cookie/services/cookies.service";
import { Headers, RequestOptions } from "@angular/http";
import { Injectable } from "@angular/core";
@Injectable()
export class CustomRequestOptionsService {
constructor(
private cookieService: CookieService
) { }
defaultRequestOptions() {
return new RequestOptions({
headers: new Headers({
'Content-Type': 'application/json',
}),
withCredentials: true
});
}
authorizationRequestOptions() {
return new RequestOptions({
headers: new Headers({
'Content-Type': 'application/json',
'X-CSRFToken': this.cookieService.get('csrftoken')
}),
withCredentials: true
});
}
}
,然后在您遇到安全API的服务中像这样使用它
and then in your service where you hit secure APIs use it like this
// Officer service
import { Http, Response} from "@angular/http";
import { Injectable } from "@angular/core";
import "rxjs/add/operator/map";
// Services
import { CustomRequestOptionsService } from "../shared/custom-request-options.service";
@Injectable()
export class OfficerService {
private officerDashboardUrl = `http://${process.env.API_URL}` + '/api/v1/officers/detail';
constructor(
private http: Http,
private customRequestOptionService: CustomRequestOptionsService
) { }
getOfficer(officerId: number) {
return this.http.get(`${this.officerDashboardUrl}/${officerId}/`,
this.customRequestOptionService.authorizationRequestOptions())
.toPromise()
.then((response: Response) => {
return response.json();
})
.catch((error: any) => {
return Promise.reject(error.message || error)
});
}
}
这篇关于Angular 2的Django会话身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!