Flask-Login doesn't set cookies to browser with angular? Flask-Login doesn't set cookies to browser with angular? flask flask

Flask-Login doesn't set cookies to browser with angular?


You can't set browser cookies by using the server session. You'd have to send cookies in the response. If you want to set cookies in the response, you could do something like this:

from flask import make_response # and your other stuff# ... other imports ...def login():# ... some authentication code here to get your access_token (like a jwt)...    resp = make_response(redirect('http://localhost:4200')) # your angular app    resp.set_cookie('token', access_token) # set the cookie on the response header for the browser to extract    return resp # return the response with the new cookie attached

Since your client application isn't on the same domain as your server application, setting the session isn't going to help you in the way you want for authentication. The best way to do what you want is to pass a JWT back and forth between client and server.

One thing you can try to do (if you want to set some kind of authentication on the front end) would be to authenticate your user return a JWT back to Angular. You could then set an http header to come to the backend each time. The backend would parse the request and extract the JWT from the header. You would then use that header to authenticate the user's request to your backend by decrypting the JWT when it comes in. There is a great deal of literature on this. I'll put in some good tutorials at the end of this post.

You can use (in Angular) an HttpInterceptor. Something like this:

import { Injectable } from "@angular/core";import { HttpInterceptor, HttpHandler, HttpEvent } from "@angular/common/http";import { AuthService } from "../auth/auth.service";import { HttpRequest } from '@angular/common/http';import { Observable } from "rxjs";@Injectable()export class TokenInterceptor implements HttpInterceptor {  constructor(public auth: AuthService) { }  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {    if (this.auth.isLoggedIn()) {      request = request.clone({        setHeaders: {          Authorization: `Bearer ${this.auth.getToken()}`        }      });    }    return next.handle(request);  }}

You could have an Auth service like so:

import { Injectable } from '@angular/core';import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';import { CookieService } from 'ngx-cookie-service';import { map } from 'rxjs/operators';import { environment } from '../../environments/environment';@Injectable({  providedIn: 'root'})export class AuthService {  redirectUrl: string;  // cookie service from ngx-cookie-service  constructor(private http: HttpClient, private cookieService: CookieService) { }  checkToken() {    return this.cookieService.check('token');  }  getToken() {    return this.cookieService.get('token');  }  loginWithUsernameAndPassword(userName: string, password: string) {    return this.http.post<any>(`${environment.API_URL}/auth/login`,        new HttpParams({fromObject: {userName, password}}),        {          headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')        }      ).pipe(map(user => {        if (user && user.token) {          this.cookieService.set('token', user.token);        }        return user;      }));  }  logout() {    this.cookieService.delete('token');  }  isLoggedIn() {    return this.cookieService.check('token');  }  registerWithUsernameAndPassword(userName, password, email) {    return this.http.post<any>(`${environment.API_URL}/auth/create`,      new HttpParams({fromObject: {userName, password, email}}),      {        headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded')      }    )      .pipe(map(user => {        console.log(user);        return user;      }));  }}

In your AppModule you can then specify a provider called HTTP_INTERCEPTORS and use the HttpInterceptor you created -- in my case, I would call it TokenInterceptor:

import { BrowserModule } from '@angular/platform-browser';import { NgModule } from '@angular/core';import { AppComponent } from './app.component';import { AppRoutingModule } from './app-routing/app-routing.module';import { SharedModule } from './shared/shared.module';import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';import { CookieService } from 'ngx-cookie-service';import { AuthService } from './auth/auth.service';import { TokenInterceptor } from './interceptors/token.interceptor';@NgModule({  imports: [    BrowserModule,    AppRoutingModule,    SharedModule,    HttpClientModule  ],    declarations: [    AppComponent,  ],  exports: [],  providers: [    AuthService,    CookieService,    {      provide: HTTP_INTERCEPTORS,      useClass: TokenInterceptor,      multi: true    }  ],  bootstrap: [AppComponent]})export class AppModule {}

A good reference for the interceptor: https://angular.io/api/common/http/HttpInterceptorand: https://medium.com/@ryanchenkie_40935/angular-authentication-using-the-http-client-and-http-interceptors-2f9d1540eb8

And the canonical source on Flask would be Miguel Grinberg, who has written some JWT authentication tutorials -- https://blog.miguelgrinberg.com/post/json-web-tokens-with-public-key-signatures

here's another tutorial for JWT in Flask as well: https://realpython.com/token-based-authentication-with-flask/