Yii2:在Rest应用程序中启用Cookie

问题描述:

我有一个用yii编写的无头应用程序,使用yii2 api的Angular应用程序。目前即时通讯使用本地存储的令牌,但我读了这个link并希望将令牌存储在cookie中。Yii2:在Rest应用程序中启用Cookie

验证行动:

\Yii::$app->response->cookies->add(new Cookie([ 
    'name' => 'token', 
    'value'=> $token->__toString() 
])); 

AuthMethod:

if (($cookie = $cookies->get('token')) !== null) { 
    die('Token found in cookie'); 
    $token = $parser->parse($cookie->value); 
} 

令牌是百达null,所以它看起来像饼干默认情况下,休息控制器/ JSON响应,怎么被禁用我可以启用它吗?

对于未来编参考,如果链接是死它得出结论认为cookies是比本地存储更好地为JWT令牌

饼干,与仅Http cookie的标志一起使用时,它们不能通过JavaScript和对XSS免疫。您还可以设置安全cookie标志以保证cookie仅通过HTTPS发送。这是过去利用cookie存储令牌或会话数据的主要原因之一。现代开发人员不愿意使用cookie,因为他们传统上要求将状态存储在服务器上,从而打破了RESTful最佳实践。如果您要在Cookie中存储JWT,则作为存储机制的Cookie不需要将状态存储在服务器上。这是因为JWT封装了服务器为请求提供服务所需的所有内容。

编辑

使用本地PHP $ _COOKIE的cookie可以被yii2应用程序读取,但setcookie()函数不起作用。看起来,yii2-rest控制器在发送响应之前会剥去标题。

+0

您正在使用Angularjs«1.6.x»或Angu大写«2,4»? 该解决方案既适用于Angular也适用于您的API,所以第二个问题是,您是否使用YII2 APi? – moplin

+0

请评论你在angular和Yii2上使用的版本。也许我会有一个答案。 – moplin

+0

另外,你可以评论你如何管理JII内部的JWT,你是否使用扩展? – moplin

我会让我的第一次尝试回答,我希望这是有道理的,并帮助您和他人的cookie。

我问你关于角度版本,因为,因为你知道角度作为一个页面的应用程序,我将需要概念代码的证明来显示我的观点«我将asume angularjs 1.6.x»,这意味着它的工作原理远离你的YII2,除非你正在渲染角度。现在有两种方法可以“绕过”这个以设置cookie。 第一个将在角度内设置你的cookie,在你的控制器上调用你的登录端点,并让它返回令牌(在我的例子中,我不是只为了速度做这个部分)。然后使用$ cookie服务«你将不得不导入角度曲奇»来构建cookie。 另一种方式可能是在Yii中调用和终结点“看看actionSetCookie示例”并在其中构建cookie,我不喜欢那种对我来说看起来很脏的。

现在出现了一个大问题,您可能有,yii使用cookie验证“签署cookie”,但是当您在外部构建cookie时,此cookie将无法工作。所以...为了使这个例子工作,你将不得不关闭cookie验证。

components' => [ 
    'request' => [ 
    'enableCookieValidation' => false, //<---make it false 
    'enableCsrfValidation' => true, 
    'cookieValidationKey' => 'hdfghdsrthrgfdhfghthdrtth', 
    'parsers' => [ 
     'application/json' => 'yii\web\JsonParser', 
    ] 
    ], 
    ... 
] 

现在,我做了一个工作测试。
首先我做了两个简单的动作来测试我实际上是在建造cookie。我可以用邮递员给他们打电话。

public function actionSetCookie() 
{ 
    Yii::$app->response->format = Response::FORMAT_JSON; 
    $session = Yii::$app->session; 
    $cookies_rsp = Yii::$app->response->cookies; 
    $cookies_rsp->add(new Cookie([ 
     'name' => 'token', 
     'value' => 'tt-eyJhbGciOiJIUzI1NiIs...', 
    ])); 
    $response = ['cookie set'=>$cookies_rsp]; 
    return $response; 
} 

public function actionCookie() 
{ 
    Yii::$app->response->format = Response::FORMAT_JSON; 
    $session = Yii::$app->session; 
    $cookies = Yii::$app->request->cookies; 
    $token = ''; 
    if (isset($cookies['token'])) { 
     $token = $cookies['token']->value; 
    } 
    $response = ['token'=>$token]; 
    return $response; 
} 

我做出角两个控制器做出解释:

.controller('View1Ctrl', ['$cookies', function ($cookies) { 
    console.log('View1Ctrl++++++++'); 
    var vm = this; 
    vm.title = 'Customers'; 
    $cookies.remove('token'); 
    $cookies.put('token', 'my-angular-token'); 
    vm.myToken = $cookies.get('token'); 
    console.log('myToken', vm.myToken); 
} 

.controller('View2Ctrl', ['$http', function ($http) { 
    console.log('View2Ctrl'); 
    //Lest set the cookie 
    $http({ 
    method: 'GET', 
    url: 'http://test.dev/site/set-cookie' 
    }).then(function successCallback(response) { 
     console.log('response', response); 
    }, function errorCallback(response) { 
     console.error('err', response) 
    }); 
} 

现在这里有云

在溶液1«View1Ctrl»,我建立使用$饼干cookie服务,我可以使用动作actionCookie对其进行验证,只有在enableCookieValidation为false时才会读取。

在解决方案2«View2Ctrl»上,我使用actionSetCookie作为http获取端点,但设置的cookie不多,此cookie将与enableCookieValidation一起使用false或true。

结论
记住,角度和yii2是“应该”是不可知的,独立的,所以你必须要消耗警予作为终点。

您必须选择enableCookieValidation,具体取决于您的解决方案。我不确定是否有办法用角度来做,但可能不是一个好主意,因为您必须在角度内发布cookieValidationKey。

我个人不喜欢使用cookie作为apis,因为如果您正在开发移动应用程序,那么无状态和无cookie的想法会有所帮助,“我可能对此错误”。

关于邮递员,它将与解决方案2一起工作,除非您关闭enableCookieValidation。请记住,这个验证会为cookie中的令牌添加一些盐,也就是额外的安全性。
最后在p [ostman上,如果enableCookieValidation设置为true并且玩具手动制作cookie,Yii将不会收到Cookie,因为安全。

enter image description here

只是为了说明这个安全相关的cookie的签署,我拍摄的这部影片。我希望这将有所帮助。所以这是因为CookieValidation是真实的。这是不使用PHP默认cookie服务的理由,但tu使用Yii提供的服务。在视频中,您将看到这个系统对于每个cookie都非常具体。和为什么你可能看不到邮递员的cookie。

如果您将CookieValidation设置为false,则此手动Cookie,PHP默认cookie实际上会再次运行,但不太安全。

Video

关于在博客上和角度的讨论,记得使用$ HTTP调用时的角度实际上保护您的应用程序,它是在这个意义上非常安全的,但也不要忘记使用ngSanitize您应用程序。
更多内容:
https://docs.angularjs.org/api/ng/service/ $ HTTP#跨站点请求伪造XSRF保护
https://docs.angularjs.org/api/ngSanitize
https://docs.angularjs.org/api/ngCookies/service/ $饼干

最后,如果我找到固定的cookie一样Yii2从角度做一些事情我会将其添加到帖子中。

希望它有帮助。

万一你想看看我的代码

https://github.com/moplin/testdev

+1

这实际上归结为一个POSTman问题,我相信。我仍然无法获取邮递员“cookies”-tab中的cookie,但是您提供的两个功能确实有效。我甚至没有想过要测试它,而且代码可能一直工作。感谢您的全面回答。 –

+0

谢谢。我建议你玩enableCookieValidation配置,我相信这是使用邮递员的关键。因为Yii cookie管理非常安全,并且没有正确的密钥(图像)就不会读取cookie。 – moplin

+0

因此,我制作了一个小视频,介绍了cookie验证以及它如何影响cookie的阅读。 [视频](https://youtu.be/QIKl_JCjMB4) – moplin

原生php $ _COOKIE呢?尝试设置并获得使用这个

+0

这确实解决了它的阅读饼干,但我仍然无法存储它们。难道是响应是'application/json'? –

如果你想在服务器端访问cookie,所以你必须发送它们以及你的请求。默认情况下,Angular不会在XHR请求中发送cookie。要请求允许Cookie添加此下面的代码:在角$http

.config(function ($httpProvider) { 
    $httpProvider.defaults.withCredentials = true; 

}); 

OR

$http.get("URL", { withCredentials: true }) 
    .success(function(data, status, headers, config) {}) 
    .error(function(data, status, headers, config) {}); 

见用法部分请确保您还设置在客户端该Cookie,使用JavaScript,然后检查你的Chrome控制台是否有http请求,确保它也发送cookie。

务必从$cookies = Yii::$app->request->cookies; http://www.yiiframework.com/doc-2.0/guide-runtime-sessions-cookies.html#reading-cookies

读取cookies和写作使用$cookies = Yii::$app->response->cookies; http://www.yiiframework.com/doc-2.0/guide-runtime-sessions-cookies.html#sending-cookies

+0

我正在使用Chrome中的POSTman插件,并且该cookie不会在响应中返回。甚至还没有尝试与前端应用程序呢。 –

+1

@Jørgen确保你从'Yii :: $ app-> request-> cookies;'读取cookie,并使用'Yii :: $ app-> response-> cookies写入;' –

+1

是的。我知道。我已经仔细检查过了。 –

如果令牌是令牌,你能不能在REST控制器使用接入 的autheticator行为

yii\filters\auth\HttpBasicAuth; 
yii\filters\auth\HttpBearerAuth; 
yii\filters\auth\QueryParamAuth; 

当收到第一次令牌将其保存到浏览器中的曲奇