Laravel 和 Dropbox WebAuth:"Missing CSRF token in session"

Laravel and Dropbox WebAuth: "Missing CSRF token in session"

我正在使用 Laravel 5.0 并尝试使用 Dropbox 进行授权。我松散地遵循这个例子:http://dropbox.github.io/dropbox-sdk-php/api-docs/v1.1.x/class-Dropbox.WebAuth.html

当我进入 /start 时。我被重定向到 Dropbox 并单击 "Allow",但是当我被重定向回 /finish 时,我一直在会话中收到 Missing CSRF token。有人有什么想法吗?我读到 $_SESSION 在 Laravel 中不起作用,但我不确定还有什么办法可以解决。

这是我正在使用的代码:

public function start()
{   
    $authorizeUrl = $this->getWebAuth()->start();

    return redirect()->away($authorizeUrl);
}

public function finish()
{       
    $test = $this->getWebAuth()->finish($_GET);

    dd($test);
}

private function getWebAuth()
{   
    $appKey = 'key';
    $appSecret = 'secret';
    $appName = 'name';
    $appRedirect = 'http://example.com/finish';

    $appInfo = new Dropbox\AppInfo($appKey, $appSecret);
    $csrfTokenStore = new Dropbox\ArrayEntryStore($_SESSION, 'dropbox-auth-csrf-token');
    $webAuth = new Dropbox\WebAuth($appInfo, $appName, $appRedirect, $csrfTokenStore);

    return $webAuth;
}

更新 1:

好的,所以我试着让它与 Laravel Socialite and the Dropbox Socialite provider. I changed my code to what is below, but I get an error when I hit /start. Driver [dropbox] not supported. I got really confused on step 3 的说明一起工作,所以也许我在那里做错了。

composer.json

"require": {
    "laravel/framework": "5.0.*",
    "dropbox/dropbox-sdk": "1.1.*",
    "laravel/socialite": "~2.0",
    "socialiteproviders/dropbox": "~1.0"
},

控制器

use Socialite;

class ExampleController extends Controller {

    public function start()
    {   
        return Socialite::with('dropbox')->redirect();
    }

    public function finish()
    {       
        $user = Socialite::with('dropbox')->user();

        dd($user->token);
    }
}

config/app.php

'providers' => [
    //'Laravel\Socialite\SocialiteServiceProvider',
    'SocialiteProviders\Manager\ServiceProvider',
],

'aliases' => [
    'Socialite' => 'Laravel\Socialite\Facades\Socialite',
],

app/Providers/EventServiceProvider.php

protected $listen = [
    'SocialiteProviders\Manager\SocialiteWasCalled' => [],
];

更新二:

我弄明白了,我添加了这个并且成功了。

app/Providers/EventServiceProvider.php

protected $listen = [
    'SocialiteProviders\Manager\SocialiteWasCalled' => [
        'SocialiteProviders\Dropbox\DropboxExtendSocialite@handle',
    ],
];

注意: 使用@Blaatpraat 的回答中的 Dropbox 包通常比这更好。不过,如果您执意要使用自己的逻辑:

Laravel 5 POST 路由(Dropbox 在流程结束时回发给您)默认受 the CSRF protection middleware 保护。因为 Dropbox 不知道您的 Laravel 应用程序的 CSRF 令牌(也不知道发送一个),所以缺少 _token 参数并使中间件失败。

您需要修改 app/Http/Middleware/VerifyCsrfToken.php 以豁免这条路线。上面写着:

return parent::handle($request, $next);

您需要这样的东西来绕过某些路由的 CSRF 检查:

if(\Request::is('finish') { return $next($request); }
return parent::handle($request, $next);

为什么要重新发明轮子,如果你有一个包装器可以为你做到这一点:

https://github.com/GrahamCampbell/Laravel-Dropbox

原因是 POST 路由受 CSRF 保护。如果您不想使用包装器,则需要禁用此安全层,但没有人会建议这样做。

更好的是使用 Laravel Socialite. Only the fact is here that Dropbox is not natively supported in it, but this package 将解决这个问题。

感谢 ceejayoz 的帮助!