Flask-Security:Angular 请求中缺少 CSRF SESSION 令牌

问题描述 投票:0回答:1

我有一个使用 Flask-Security 扩展的 Flask 应用程序。以下是我的应用程序的初始化方式:

app = Flask(__name__)
app.config['DEBUG'] = True
CORS(app)
CSRFProtect(app)

app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

app.config['SECRET_KEY'] = os.environ.get("SECRET_KEY", 'pf9Wkove4IKEAXvy-cQkeDPhv9Cb3Ag-wyJILbq_dFw')
app.config['SECURITY_PASSWORD_SALT'] = os.environ.get("SECURITY_PASSWORD_SALT", '146585145368132386173505678016728509634')
app.config["SECURITY_EMAIL_VALIDATOR_ARGS"] = {"check_deliverability": False}

app.teardown_appcontext(lambda exc: db_session.close())

# Setup Flask-Security
user_datastore = SQLAlchemySessionUserDatastore(db_session, User, Role)
app.security = Security(app, user_datastore)

我还有另一个基于 Angular 的应用程序与 Flask 应用程序进行通信。在

OnInit
函数中,我确保提供了 CSRF 令牌:

this.http.get("http://localhost:5000/login")
  .subscribe({
    next: (response: any) => {
      let crsftoken = response.response.csrf_token;
      console.log("CRFS TOKEN aus GET" + crsftoken);
      localStorage.setItem("crsftoken", crsftoken);
    },
    // ...
  });

这工作正常,但是当我尝试使用登录表单登录用户时,CSRF 令牌似乎没有包含在请求中。这是提交表单时执行的代码:

const formData = new FormData();
formData.append('email', this.loginForm.controls.username.value || "");
formData.append('password', this.loginForm.controls.password.value || "");
this.http.post("http://localhost:5000/login", formData)
  .subscribe({
    next: (response: any) => {
      console.log(response);
    },
    // ...
  });

当我执行此代码时,我收到“错误请求”响应,其中包含消息“CSRF 会话令牌丢失”。会话令牌似乎没有随请求一起发送,但我不确定为什么。

在第一次调用“http://localhost:5000/login”的

GET
方法期间,我可以在响应和
Set-Cookie
标头中看到会话。但是,它似乎没有存储在浏览器中。因此,它不会随后续请求一起发送。

添加:当然,我使用 HTTP 拦截器将 Csrf-Token 放入每个请求的标头中,请参阅:

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    let crsftoken = localStorage.getItem('crsftoken');
    let headers = request.headers;
    headers = headers.set("X-CSRF-TOKEN", crsftoken || "");
    request = request.clone({
      headers : headers
    });
    return next.handle(request);
  }
}

我做错了什么?也许我误解了 CSRF 令牌和 CSRF 会话令牌之间的区别? 任何见解或建议将不胜感激。谢谢!

python angular flask flask-security flask-session
1个回答
0
投票

关于执行此操作的方法有相当完整的文章:https://flask-security-too.readthedocs.io/en/stable/patterns.html#csrf

一种方法 - 获取您收到的 CSRF 令牌并将其作为“X-CSRF-Token”发送。 会话 cookie 确实需要发送 - 但我会确保首先正确发送您的 CSRF 令牌。

引用的文档还解释了如何使用 cookie 来执行此操作 - Angular (httpclient) 内置了对此的支持。

© www.soinside.com 2019 - 2024. All rights reserved.