从其他域中的应用程序登录RESTful Laravel API

时间:2015-04-10 18:32:14

标签: javascript php angularjs rest laravel

如何配置Laravel 5.0从其他域登录?说明一下,我们有一个Laravel RESTful API,有些用户在你自己的域上创建Angular.js应用程序和托管。

当尝试登录这些应用时,登录返回true,但是在下一个请求时会丢失会话。

我认为这可能与CORS有关,但我设置了正确的标题。

我的标题:

在apache虚拟主机上设置的Hearders:

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT, PATCH, DELETE"
Header always add Access-Control-Allow-Headers "accept, origin, x-requested-with, content-type, x-application-token, x-csrf-token, x-password-reset-token"
Header always add Access-Control-Expose-Headers "x-csrf-token"

1 个答案:

答案 0 :(得分:3)

设置CORS只是使这项工作迈出的一小步。 Please give this article a read

您遇到的问题是来自其他域的后续请求不会发送任何类型的令牌或标识符,laravel可以使用这些令牌或标识符来决定用户正在发出请求。您应该考虑使用JWT库。

laravel-jwt对于实现这一点非常可靠。 只需将CORS添加到您的应用中就不足以让它正常工作。

Laravel需要知道用户发出了什么请求,上面的库附带了中间件和方法来轻松完成此任务。

从较高层面来看,需要发生的一些步骤是:

1)设置角度登录控制器/服务

    $scope.login = function () {

        // Send The Login Request
        UserService.authenticate($scope.formData)
            .$promise.then(function(data) {

                // If Successfully Authed
                if (data.success && data.hasOwnProperty('token')) {

                    // Set Cookies
                    UserService.setCurrentUser(data.user);
                    UserService.setUserToken(data.token);                        

                    // Fire Login Event
                    return authService.loginConfirmed(data);

                } else {
                    // Else Errors Logging In
                    AlertService.addAlert(data.error, 'danger');
                }
            });
        };

2)使用laravel-jwt处理auth:

public function authenticate()
{
    $credentials = $this->request->only('username', 'password');

    try {
        // Verify Credentials & Create Token for User
        if (! $token = $this->auth->attempt($credentials)) {
            return response()->json(['success' => false, 'error' => 'Invalid Credentials.'], 401);
        }
    } catch(JWTException $e) {
        // Something went wrong encoding the token.
        return response()->json(['success' => false, 'error' => 'Could not create token.'], 401);
    }

    return response()->json(['success' => true, 'user' => $user->toArray());

}

3)添加角度拦截器以为后续请求添加授权标头:

 //...your interceptor
 return {
    'request': function (config) {

        // Get Current JWT
        var cookieToken = $cookieStore.get('currentToken');

        // If Authed, Tack on Auth Token
        if (cookieToken) {
            config.headers['Authorization'] = 'Bearer: ' + cookieToken;
        }

        return config || $q.when(config);
    }
}
//...remainder of interceptor

4)添加中间件以通过令牌验证用户

public function handle($request, \Closure $next)
{
    if (! $token = $this->auth->setRequest($request)->getToken()) {
        return $this->respond('tymon.jwt.absent', 'token_not_provided', 400);
    }

    try {
        $user = $this->auth->authenticate($token);
    } catch (TokenExpiredException $e) {
        return $this->respond('tymon.jwt.expired', 'token_expired', $e->getStatusCode(), [$e]);
    } catch (JWTException $e) {
        return $this->respond('tymon.jwt.invalid', 'token_invalid', $e->getStatusCode(), [$e]);
    }

    if (! $user) {
        return $this->respond('tymon.jwt.user_not_found', 'user_not_found', 404);
    }

    return $next($request);
}

需要注意的是,此代码不会对您有效,而只是为了向您展示实现的内容

这方面的完整工作实现超出了stackoverflow的答案,我建议在网上其他地方阅读。

如果两个网站都是Laravel应用程序,那么您可能只需要在配置中调整Cookie域。