gpt4 book ai didi

带有CSRF : "CSRF token not found in session"?的Playframework

转载 作者:行者123 更新时间:2023-12-04 07:53:21 27 4
gpt4 key购买 nike

我正在使用 Playframework 及其内置 CSRF 过滤器和 Security.Authenticator 系统制作一个简单的身份验证系统,但我面临一个问题:

当用户填写他的登录名/密码并提交输入时,我有以下错误:

CSRF token not found in session



我检查了我的表单,CSRF token 确实存在并且正确放置(在标签内)

这是我的 routes :
GET     /login                      controllers.Authentication.login
POST /login controllers.Authentication.authenticate

还有我的 Authentication.java类(class) :
@play.filters.csrf.AddCSRFToken
public static Result login() {
if (Session.getAccount() != null) {
return redirect(controllers.routes.Instances.list());
}

LoginForm loginForm = new LoginForm();
if (ctx().session().containsKey("email")) {
loginForm.setEmail(ctx().session().get("email"));
}

if (request().queryString().containsKey("disconnected")) {
flash("warning", Messages.get("secure.logout")); // TODO : Warning flash message
}

Form<LoginForm> form = Form.form(LoginForm.class).fill(loginForm);
return ok(views.html.login.render(form));
}

@play.filters.csrf.AddCSRFToken
@play.filters.csrf.RequireCSRFCheck
public static Result authenticate() {
Form<LoginForm> form = Form.form(LoginForm.class).bindFromRequest();
if (form.hasErrors()) {
return badRequest(views.html.login.render(form));
}

LoginForm login = form.get();
Account account = Account.findByEmail(login.getEmail());

if (account == null || !account.checkPassword(login.getPassword())) {
form.reject("email", "secure.invalid.login");
return badRequest(views.html.login.render(form));
}

String next = null;
if (ctx().session().containsKey("next")) {
next = ctx().session().get("next");
if ("".equals(next)) {
next = null;
}
}

session().clear();
session("email", login.getEmail());

if (next != null) {
return redirect(next);
} else {
return redirect(controllers.routes.Instances.list());
}
}

我在 application.conf 中设置的属性:
csrf.token.name="csrf"
csrf.sign.tokens=true

这是我的表格(以显示 token 已正确定位):
<form action="@controllers.routes.Authentication.authenticate" method="post" class="form-vertical" role="form">
<fieldset>
@defining(form("email")) { element =>
<div class="form-group fade-in two@if(element.hasErrors){ has-error}">
<label class="control-label" for="login-form-@element.name">Email:</label>
<input type="email" name="@element.name" id="login-form-@element.name" class="form-control" value="@element.value" placeholder="Enter your email" required />
@element.errors.map { error => <span class="help-block">@play.i18n.Messages.get(error.message)</span>}
</div>}
@defining(form("password")) { element =>
<div class="form-group fade-in three@if(element.hasErrors){ has-error}">
<label class="control-label" for="login-form-@element.name">Password:</label>
<input type="password" name="@element.name" id="login-form-@element.name" class="form-control" value="@element.value" placeholder="Enter your password" required />
@element.errors.map { error => <span class="help-block">@play.i18n.Messages.get(error.message)</span>}
</div>}
<div class="form-group actions fade-in four">
<div class="text-right">
<input type="submit" name="save" value="Sign me in" class="btn btn-primary" />
@helper.CSRF.formField
</div>
</div>
</fieldset>
</form>

更新 1 : 我删除了所有 @addCSRFToken@requireCSRFToken并根据@rhj 建议定义了一个全局 CSRF token 。现在我得到了这个错误:

Invalid token found in form body



但是正如您在 HTML 表单中看到的那样, token 放置在表单内并且应该被识别!

更新 2 : 最让我困扰的是,这个问题只出现在登录页面,其他地方没有!是否有一些 session 要先启用?我想不是,但也许?!

更新 3 : 更奇怪,我刚刚发现如果我改变 csrf.token.name的值并重新加载页面,它的工作原理。然后,如果我注销,打开一个新页面并再次尝试登录,它会失败并显示消息 Invalid token found in form body .如果我再次更改 csrf.token.name 的值再做一次,它会再次起作用。

更新 4 : 我缩小了问题的范围。我也使用 play.mvc.Security.Authenticator,似乎只有当我在 redirect() 之后显示页面时, token 验证才会失败。 .如果我直接进入登录页面,则不会显示错误消息。

最后更新! : 终于找到问题了,是在另一个我没有怀疑的类中,它被调用并清除了 session ,使 token 无用!

最佳答案

最后,问题出在我代码的另一部分,该部分正在清理 login() 中的 session 。方法,用它删除 csrf token ......

关于带有CSRF : "CSRF token not found in session"?的Playframework,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26136744/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com