2015-04-10 17 views
13

Tôi rất ấn tượng với cách tạo đơn giản REST api trong Yii2 đơn giản như thế nào. Tuy nhiên, tôi gặp sự cố nhỏ khi hiểu Xác thực cơ bản. Nhu cầu của tôi là hoàn toàn đơn giản và tôi muốn giải pháp của tôi để làm theo.Yii2 REST Đơn giản hóa BasicAuth

Tôi cần xác thực mã thông báo cơ bản tại đây. Tôi thậm chí không chống lại hardcoding nó cho bây giờ, nhưng đây là những gì tôi đã làm cho đến nay.

Tôi có bảng cơ sở dữ liệu để giữ ApiAccess tôi ít token (id, access_token)

ApiAccess.php - Mô hình - LƯU Ý: IDE cho thấy lỗi cú pháp ở dòng đầu tiên này

class ApiAccess extends base\ApiAccessBase implements IdentityInterface 
{ 
    public static function findIdentityByAccessToken($token, $type = null) 
    { 
    return static::findOne(['access_token' => $token]); 
    } 
} 

Mô-đun .php - trong hàm init()

\Yii::$app->user->enableSession = false; 

Tôi đã tạo một ApiContro ller rằng mỗi danh từ tiếp theo kéo dài

ApiController.php

use yii\rest\ActiveController; 
use yii\filters\auth\HttpBasicAuth; 
use app\models\db\ApiAccess; 

class ApiController extends ActiveController 
{ 
    public function behaviors() 
    { 
     $behaviors = parent::behaviors(); 
     $behaviors['authenticator'] = [ 
     'class' => HttpBasicAuth::className(), 
     ]; 
    return $behaviors; 
    } 
} 

Khi đứng, truy cập vào một thiết bị đầu cuối api trong trình duyệt sẽ nhắc cho một tên người dùng và mật khẩu. Yêu cầu thông qua REST Client hiển thị lỗi truy cập.

Làm cách nào để kết hợp đúng HttpBasicAuth với mô hình ApiAccess của tôi?

HOẶC

Làm thế nào để hardcode một access token api? (Tùy chọn đầu tiên rõ ràng là tốt nhất)

Trả lời

21

Hãy xem và cố gắng hiểu "yii" cách xác thực cơ bản cho REST.

1st. Khi bạn thêm hành vi vào trình điều khiển REST của mình, bạn bật quyền xác thực cơ bản:

$behaviors['authenticator'] = [ 
    'class' => HttpBasicAuth::className(), 
    ]; 

Như bạn đã làm. Nó có nghĩa là gì? Điều đó có nghĩa là ứng dụng của bạn sẽ phân tích cú pháp tiêu đề ủy quyền của bạn. Có vẻ như:

Authorization : Basic base64(user:password) 

Đây là mẹo cho yii2. Nếu bạn nhìn vào mã cẩn thận hơn, bạn sẽ thấy yii có sử dụng access_token từ lĩnh vực sử dụng, vì vậy tiêu đề của bạn sẽ giống như thế:

Authorization : Basic base64(access_token:) 

Bạn có thể phân tích tiêu đề này bằng cách riêng của bạn, nếu bạn muốn thay đổi hành vi này:

$behaviors['authenticator'] = [ 
      'class' => HttpBasicAuth::className(), 
      'auth' => [$this, 'auth'] 
     ]; 
.... 
public function auth($username, $password) 
    { 
     return \app\models\User::findOne(['login' => $username, 'password' => $password]); 
    } 

Điều cần làm. Bạn phải triển khai chức năng findIdentityByAccessToken() từ identityInterface. Tại sao IDE của bạn phàn nàn?

class User extends ActiveRecord implements IdentityInterface 

Đây là cách khai báo lớp người dùng của bạn.

Từ thực hiện và cấu trúc của bạn:

public static function findIdentityByAccessToken($token, $type = null) 
    { 
    return static::findOne(['access_token' => $token]); 
    } 

bạn không trở về đối tượng của lớp mà thực hiện giao diện danh tính.

Làm thế nào để làm cho nó đúng cách? Thêm cột access_token vào bảng người dùng của bạn và trả về mô hình người dùng của bạn (bạn có thể xem nó như thế nào ở đây - https://github.com/yiisoft/yii2-app-advanced/blob/master/common/models/User.php) Nếu bạn làm điều này - mã mặc định sẽ hoạt động với triển khai findIdentityByAccessToken() của bạn.

Nếu bạn không muốn thêm trường vào bảng người dùng - hãy tạo trường mới với trường user_id,access_token. Sau đó, triển khai của bạn sẽ trông giống như:

public static function findIdentityByAccessToken($token, $type = null) 
    { 
    $apiUser = ApiAccess::find() 
     ->where(['access_token' => $token]) 
     ->one(); 
    return static::findOne(['id' => $apiUser->user_id, 'status' => self::STATUS_ACTIVE]); 
    } 

Hy vọng tôi có thể bao gồm tất cả các câu hỏi của bạn.

+0

Tôi có tính năng này hoạt động và xem nó hoạt động như thế nào bây giờ. Cảm ơn bạn. Tôi vẫn gặp sự cố liên quan đến việc ghi đè xác thực LDAP đã có tại chỉ cho mô-đun này. Tôi sẽ đăng một câu hỏi riêng nếu tôi không thể tự mình giải quyết nó. – Joshua

+0

findOne không mã hóa mật khẩu để xem nó có khớp với password_hash không - làm cách nào để kết hợp validatePassword với findOne? – Cymbals

+0

@Cymbals http://www.yiiframework.com/doc-2.0/guide-security-passwords.html –