【问题标题】:TokenMismatchException error on iOS 9.1 SafariiOS 9.1 Safari 上的 TokenMismatchException 错误
【发布时间】:2015-12-18 01:35:20
【问题描述】:

我只在手机上得到这个TokenMismatchException。

iOS 9.1 / iPhone 6 Plus / Safari

我试过添加这个

<meta name="csrf-token" content="{{ csrf_token() }}">

这在我的登录表单中

{{ csrf_field() }}


不适用于我的 iPhone (iOS 9.1 / iPhone 6 Plus / Safari)

但我仍然可以登录计算机/笔记本电脑。


HTML 表单

<form method="POST" action="http://localhost:8888/sign-in" accept-charset="UTF-8" class="form-horizontal" role="form">
    <input name="_token" type="hidden" value="AMzt0uxA2vv79VGmR6WLtaVR5jGa9ZDbv07uI2Pb">
    <p class="pad-btm">Sign In to your account</p>
    <div class="form-group">
        <div class="input-group">
            <div class="input-group-addon"><i class="fa fa-envelope"></i></div>
            <input required="" class="form-control" placeholder="Email" name="email" type="email" value="">
        </div>
    </div>
    <div class="row">
        <div class="col-xs-8"></div>
        <div class="col-xs-4">
            <div class="form-group text-right">
                <button type="submit" class="btn btn-success text-uppercase">Sign In</button>
            </div>
        </div>
    </div>
    <input type="hidden" name="_token" value="AMzt0uxA2vv79VGmR6WLtaVR5jGa9ZDbv07uI2Pb">
</form>

有人知道为什么会这样吗?


更新

它适用于 iPhone 6 Plus iOS 9.1 上的 Chrome。

【问题讨论】:

  • 那是因为您没有在 post 调用中发送 csrf 令牌,您必须在服务器上建立一个简单的 GET 调用,检索返回的 csrf 令牌并将其与您的 POST 调用一起发送为_token它会起作用。或者,简单地禁用 csrf 检查
  • 如何禁用 csrf 检查?你能回答吗?
  • 注释掉会起作用。我确信这一点,因为我对我的应用程序使用相同的方式。
  • 禁用csrf不是解决办法!!您应该真正研究为什么 CSRF 令牌未包含在移动设备上的 POST 数据中。什么手机?安卓/IOS?什么版本?什么浏览器?
  • @ihue 如果 chrome 工作,那么问题是 safari 阻止了 cookie,这只是 safari 中需要启用的设置。

标签: php laravel laravel-5 laravel-5.1


【解决方案1】:

根据您的评论和更新的问题,您可以通过编辑 app/Http/Kernel.php 文件来禁用 csrf 检查。

只需将protected $Middleware数组中的VerifyCsrfToken类注释掉

第二种方法:

我将从我的应用程序中添加一小段代码并进行解释。

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(register_url);
HttpGet httpGet = new HttpGet(token_url);
try {
    // first hit on the server url to get csrf token
    ResponseHandler<String> tokenHandler = new BasicResponseHandler();
    csrf_token = httpClient.execute(httpGet, tokenHandler);

    // Obtained Token, now we can make post call
    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
    nameValuePairs.add(new BasicNameValuePair("_token", csrf_token));
    nameValuePairs.add(new BasicNameValuePair("_device", device_id));
    nameValuePairs.add(new BasicNameValuePair("username", username));
    httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

    ResponseHandler<String> mHandler = new BasicResponseHandler();
    response = httpClient.execute(httpPost, mHandler);

此代码属于我的一个 Android 应用程序(是的,DefaultHttpClient 现在已弃用)。我编写了一个 API 端点,它从服务器返回一个 csrf_token,即 csrf_token 变量,并且 url 存储在 token_url 中。收到 csrf 令牌后,我通过将 csrf_token 传递为 _token 来使用它来进行实际的 POST 调用。

我希望代码能解释清楚。

在你的 laravel 代码中,你可以返回 csrf_token 如下

public function index()
{
    return csrf_token();
}

【讨论】:

  • 嗨,伙计,我已经尝试过了,我不再看到该消息,这很好 - 但现在我无法再登录我的应用程序了。
  • 禁用它可能会解决问题,但它可以打开许多其他问题。您正在禁用一项安全功能。
  • 是的,同样的问题,对于我的应用程序,我进行了一个简单的 get 调用来获取 csrf 令牌并将其用于我的 POST 调用。但这需要 2 次调用。
  • @VishalSh : 你能告诉我们这两个步骤吗,你在说什么?
  • @MatthewJohnson :我希望您不介意通过回答提供更多建议。希望你不要介意。
【解决方案2】:

在对这个 Safari 特定问题进行更多研究后,我了解到我需要调整我们的 Cookies 设置。

步骤:

  1. 在你的 iPhone 上,转到Settings
  2. 在设置中,选择Safari
  3. 在 Safari 中,向下滚动,选择 Block Cookies
  4. 将其更改为Always Allow
  5. 完成

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    • 2017-05-28
    • 1970-01-01
    • 2016-03-22
    相关资源
    最近更新 更多