2017-10-16 34 views
1

我有一個用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

回答

1

我會讓我的第一次嘗試回答,我希望這是有道理的,並幫助您和他人的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

0

原生php $ _COOKIE呢?嘗試設置並獲得使用這個

+0

這確實解決了它的閱讀餅乾,但我仍然無法存儲它們。難道是響應是'application/json'? –

0

如果你想在服務器端訪問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

是的。我知道。我已經仔細檢查過了。 –

0

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

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

當收到第一次令牌將其保存到瀏覽器中的曲奇