mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-11 19:20:01 +08:00
Support for other auth types.
This commit is contained in:
@@ -75,9 +75,9 @@ class User extends ActiveRecord implements IdentityInterface
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function findIdentityByToken($token)
|
||||
public static function findIdentityByAccessToken($token)
|
||||
{
|
||||
throw new NotSupportedException('"findIdentityByToken" is not implemented.');
|
||||
throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,7 +8,7 @@ class User extends \yii\base\Object implements \yii\web\IdentityInterface
|
||||
public $username;
|
||||
public $password;
|
||||
public $authKey;
|
||||
public $apiKey;
|
||||
public $accessToken;
|
||||
|
||||
private static $users = [
|
||||
'100' => [
|
||||
@@ -16,14 +16,14 @@ class User extends \yii\base\Object implements \yii\web\IdentityInterface
|
||||
'username' => 'admin',
|
||||
'password' => 'admin',
|
||||
'authKey' => 'test100key',
|
||||
'apiKey' => '100-apikey',
|
||||
'accessToken' => '100-token',
|
||||
],
|
||||
'101' => [
|
||||
'id' => '101',
|
||||
'username' => 'demo',
|
||||
'password' => 'demo',
|
||||
'authKey' => 'test101key',
|
||||
'apiKey' => '101-apikey',
|
||||
'accessToken' => '101-token',
|
||||
],
|
||||
];
|
||||
|
||||
@@ -38,10 +38,10 @@ class User extends \yii\base\Object implements \yii\web\IdentityInterface
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public static function findIdentityByToken($token)
|
||||
public static function findIdentityByAccessToken($token)
|
||||
{
|
||||
foreach (self::$users as $user) {
|
||||
if ($user['apiKey'] === $token) {
|
||||
if ($user['accessToken'] === $token) {
|
||||
return new static($user);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,9 @@ class User extends ActiveRecord implements IdentityInterface
|
||||
* @param string $token the token to be looked for
|
||||
* @return IdentityInterface|null the identity object that matches the given token.
|
||||
*/
|
||||
public static function findIdentityByToken($token)
|
||||
public static function findIdentityByAccessToken($token)
|
||||
{
|
||||
return static::find(['api_key' => $token]);
|
||||
return static::find(['access_token' => $token]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,7 +10,7 @@ In particular, Yii provides support for the following aspects regarding RESTful
|
||||
* Proper formatting of collection data and validation errors;
|
||||
* Efficient routing with proper HTTP verb check;
|
||||
* Support `OPTIONS` and `HEAD` verbs;
|
||||
* Authentication via HTTP basic;
|
||||
* Authentication;
|
||||
* Authorization;
|
||||
* Caching via `yii\web\HttpCache`;
|
||||
* Support for HATEOAS: TBD
|
||||
@@ -27,22 +27,22 @@ Let's use a quick example to show how to build a set of RESTful APIs using Yii.
|
||||
Assume you want to expose the user data via RESTful APIs. The user data are stored in the user DB table,
|
||||
and you have already created the ActiveRecord class `app\models\User` to access the user data.
|
||||
|
||||
First, check your `User` class for its implementation of the `findIdentityByToken()` method.
|
||||
First, check your `User` class for its implementation of the `findIdentityByAccessToken()` method.
|
||||
It may look like the following:
|
||||
|
||||
```php
|
||||
class User extends ActiveRecord
|
||||
{
|
||||
...
|
||||
public static function findIdentityByToken($token)
|
||||
public static function findIdentityByAccessToken($token)
|
||||
{
|
||||
return static::find(['api_key' => $token]);
|
||||
return static::find(['access_token' => $token]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This means your user table has a column named `api_key` which stores API access keys for the users.
|
||||
Pick up a key from the table as you will need it to access your APIs next.
|
||||
This means your user table has a column named `access_token` which stores API access tokens for the users.
|
||||
Pick up a token from the table as you will need it to access your APIs next.
|
||||
|
||||
Second, create a controller class `app\controllers\UserController` as follows,
|
||||
|
||||
@@ -86,7 +86,7 @@ for accessing the user data. The APIs you have created include:
|
||||
You may access your APIs with the `curl` command like the following,
|
||||
|
||||
```
|
||||
curl -i -u "Your-API-Key:" -H "Accept:application/json" "http://localhost/users"
|
||||
curl -i -u "Your-API-Access-Token:" -H "Accept:application/json" "http://localhost/users"
|
||||
```
|
||||
|
||||
which may give the following output:
|
||||
@@ -108,7 +108,7 @@ Content-Type: application/json; charset=UTF-8
|
||||
```
|
||||
|
||||
> Tip: You may also access your API via Web browser. You will be asked
|
||||
> to enter a username and password. Fill in the username field with the API key you obtained
|
||||
> to enter a username and password. Fill in the username field with the API access token you obtained
|
||||
> previously and leave the password field blank.
|
||||
|
||||
Try changing the acceptable content type to be `application/xml`, and you will see the result
|
||||
@@ -139,4 +139,57 @@ class User extends ActiveRecord
|
||||
|
||||
In the following subsections, we will explain in more details about implementing RESTful APIs.
|
||||
|
||||
TBD
|
||||
|
||||
HTTP Status Code Summary
|
||||
------------------------
|
||||
|
||||
* `200`: OK. Everything worked as expected.
|
||||
* `201`: A data item was successfully created. Please check the `Location` header for the URL to access the new data item.
|
||||
* `204`: A data item was successfully deleted.
|
||||
* `304`: Data not modified. You can use cached data.
|
||||
* `400`: Bad request. This could be caused by various reasons from the user side, such as invalid content type request,
|
||||
invalid API version number, or data validation failure. If it is data validation failure, please check
|
||||
the response body for error messages.
|
||||
* `401`: No valid API access token is provided.
|
||||
* `403`: The authenticated user is not allowed to access the specified API endpoint.
|
||||
* `404`: The requested item does not exist.
|
||||
* `405`: Method not allowed. Please check the `Allow` header for allowed HTTP methods.
|
||||
* `500`: Internal server error.
|
||||
|
||||
|
||||
Data Formatting
|
||||
---------------
|
||||
|
||||
|
||||
Implementing New API Endpoints
|
||||
------------------------------
|
||||
|
||||
|
||||
Routing
|
||||
-------
|
||||
|
||||
|
||||
Authentication
|
||||
--------------
|
||||
|
||||
|
||||
Authorization
|
||||
-------------
|
||||
|
||||
|
||||
Versioning
|
||||
----------
|
||||
|
||||
|
||||
Caching
|
||||
-------
|
||||
|
||||
|
||||
Rate Limiting
|
||||
-------------
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
@@ -32,6 +32,14 @@ class Controller extends \yii\web\Controller
|
||||
* The name of the header parameter representing the API version number.
|
||||
*/
|
||||
const HEADER_VERSION = 'version';
|
||||
/**
|
||||
* HTTP Basic authentication.
|
||||
*/
|
||||
const AUTH_TYPE_BASIC = 'Basic';
|
||||
/**
|
||||
* HTTP Bearer authentication (the token obtained through OAuth2)
|
||||
*/
|
||||
const AUTH_TYPE_BEARER = 'Bearer';
|
||||
|
||||
/**
|
||||
* @var string|array the configuration for creating the serializer that formats the response data.
|
||||
@@ -41,6 +49,14 @@ class Controller extends \yii\web\Controller
|
||||
* @inheritdoc
|
||||
*/
|
||||
public $enableCsrfValidation = false;
|
||||
/**
|
||||
* @var string the authentication type. This should be a valid HTTP authentication method.
|
||||
*/
|
||||
public $authType = self::AUTH_TYPE_BASIC;
|
||||
/**
|
||||
* @var string the authentication realm to display in case when authentication fails.
|
||||
*/
|
||||
public $authRealm = 'api';
|
||||
/**
|
||||
* @var string the chosen API version number
|
||||
* @see supportedVersions
|
||||
@@ -150,15 +166,24 @@ class Controller extends \yii\web\Controller
|
||||
|
||||
/**
|
||||
* Authenticates the user.
|
||||
* This method implements the user authentication based on HTTP basic authentication.
|
||||
* This method implements the user authentication based on an access token sent through the `Authorization` HTTP header.
|
||||
* @throws UnauthorizedHttpException if the user is not authenticated successfully
|
||||
*/
|
||||
protected function authenticate()
|
||||
{
|
||||
$apiKey = Yii::$app->getRequest()->getAuthUser();
|
||||
if ($apiKey === null || !Yii::$app->getUser()->loginByToken($apiKey)) {
|
||||
Yii::$app->getResponse()->getHeaders()->set('WWW-Authenticate', 'Basic realm="api"');
|
||||
throw new UnauthorizedHttpException($apiKey === null ? 'Please provide an API key.' : 'You are requesting with an invalid API key.');
|
||||
$request = Yii::$app->getRequest();
|
||||
if ($this->authType == self::AUTH_TYPE_BASIC) {
|
||||
$accessToken = $request->getAuthUser();
|
||||
} else {
|
||||
$authHeader = $request->getHeaders()->get('Authorization');
|
||||
if ($authHeader !== null && preg_match("/^{$this->authType}\\s+(.*?)$/", $authHeader, $matches)) {
|
||||
$accessToken = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($accessToken) || !Yii::$app->getUser()->loginByToken($accessToken)) {
|
||||
Yii::$app->getResponse()->getHeaders()->set("WWW-Authenticate', '{$this->authType} realm=\"{$this->authRealm}\"");
|
||||
throw new UnauthorizedHttpException(empty($accessToken) ? 'Access token required.' : 'You are requesting with an invalid access token.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ interface IdentityInterface
|
||||
* Null should be returned if such an identity cannot be found
|
||||
* or the identity is not in an active state (disabled, deleted, etc.)
|
||||
*/
|
||||
public static function findIdentityByToken($token);
|
||||
public static function findIdentityByAccessToken($token);
|
||||
/**
|
||||
* Returns an ID that can uniquely identify a user identity.
|
||||
* @return string|integer an ID that uniquely identifies a user identity.
|
||||
|
||||
@@ -213,7 +213,7 @@ class User extends Component
|
||||
{
|
||||
/** @var IdentityInterface $class */
|
||||
$class = $this->identityClass;
|
||||
$identity = $class::findIdentityByToken($token);
|
||||
$identity = $class::findIdentityByAccessToken($token);
|
||||
$this->setIdentity($identity);
|
||||
return $identity;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user