Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
PSDI Army
yii2
Commits
7a04dbaa
Commit
7a04dbaa
authored
Mar 03, 2014
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Support for other auth types.
parent
7b46dc34
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
103 additions
and
25 deletions
+103
-25
User.php
apps/advanced/common/models/User.php
+2
-2
User.php
apps/basic/models/User.php
+5
-5
authentication.md
docs/guide/authentication.md
+2
-2
rest.md
docs/guide/rest.md
+62
-9
Controller.php
framework/rest/Controller.php
+30
-5
IdentityInterface.php
framework/web/IdentityInterface.php
+1
-1
User.php
framework/web/User.php
+1
-1
No files found.
apps/advanced/common/models/User.php
View file @
7a04dbaa
...
@@ -75,9 +75,9 @@ class User extends ActiveRecord implements IdentityInterface
...
@@ -75,9 +75,9 @@ class User extends ActiveRecord implements IdentityInterface
/**
/**
* @inheritdoc
* @inheritdoc
*/
*/
public
static
function
findIdentityByToken
(
$token
)
public
static
function
findIdentityBy
Access
Token
(
$token
)
{
{
throw
new
NotSupportedException
(
'"findIdentityByToken" is not implemented.'
);
throw
new
NotSupportedException
(
'"findIdentityBy
Access
Token" is not implemented.'
);
}
}
/**
/**
...
...
apps/basic/models/User.php
View file @
7a04dbaa
...
@@ -8,7 +8,7 @@ class User extends \yii\base\Object implements \yii\web\IdentityInterface
...
@@ -8,7 +8,7 @@ class User extends \yii\base\Object implements \yii\web\IdentityInterface
public
$username
;
public
$username
;
public
$password
;
public
$password
;
public
$authKey
;
public
$authKey
;
public
$a
piKey
;
public
$a
ccessToken
;
private
static
$users
=
[
private
static
$users
=
[
'100'
=>
[
'100'
=>
[
...
@@ -16,14 +16,14 @@ class User extends \yii\base\Object implements \yii\web\IdentityInterface
...
@@ -16,14 +16,14 @@ class User extends \yii\base\Object implements \yii\web\IdentityInterface
'username'
=>
'admin'
,
'username'
=>
'admin'
,
'password'
=>
'admin'
,
'password'
=>
'admin'
,
'authKey'
=>
'test100key'
,
'authKey'
=>
'test100key'
,
'a
piKey'
=>
'100-apikey
'
,
'a
ccessToken'
=>
'100-token
'
,
],
],
'101'
=>
[
'101'
=>
[
'id'
=>
'101'
,
'id'
=>
'101'
,
'username'
=>
'demo'
,
'username'
=>
'demo'
,
'password'
=>
'demo'
,
'password'
=>
'demo'
,
'authKey'
=>
'test101key'
,
'authKey'
=>
'test101key'
,
'a
piKey'
=>
'101-apikey
'
,
'a
ccessToken'
=>
'101-token
'
,
],
],
];
];
...
@@ -38,10 +38,10 @@ class User extends \yii\base\Object implements \yii\web\IdentityInterface
...
@@ -38,10 +38,10 @@ class User extends \yii\base\Object implements \yii\web\IdentityInterface
/**
/**
* @inheritdoc
* @inheritdoc
*/
*/
public
static
function
findIdentityByToken
(
$token
)
public
static
function
findIdentityBy
Access
Token
(
$token
)
{
{
foreach
(
self
::
$users
as
$user
)
{
foreach
(
self
::
$users
as
$user
)
{
if
(
$user
[
'a
piKey
'
]
===
$token
)
{
if
(
$user
[
'a
ccessToken
'
]
===
$token
)
{
return
new
static
(
$user
);
return
new
static
(
$user
);
}
}
}
}
...
...
docs/guide/authentication.md
View file @
7a04dbaa
...
@@ -30,9 +30,9 @@ class User extends ActiveRecord implements IdentityInterface
...
@@ -30,9 +30,9 @@ class User extends ActiveRecord implements IdentityInterface
* @param string $token the token to be looked for
* @param string $token the token to be looked for
* @return IdentityInterface|null the identity object that matches the given token.
* @return IdentityInterface|null the identity object that matches the given token.
*/
*/
public
static
function
findIdentityByToken
(
$token
)
public
static
function
findIdentityBy
Access
Token
(
$token
)
{
{
return
static
::
find
([
'a
pi_key
'
=>
$token
]);
return
static
::
find
([
'a
ccess_token
'
=>
$token
]);
}
}
/**
/**
...
...
docs/guide/rest.md
View file @
7a04dbaa
...
@@ -10,7 +10,7 @@ In particular, Yii provides support for the following aspects regarding RESTful
...
@@ -10,7 +10,7 @@ In particular, Yii provides support for the following aspects regarding RESTful
*
Proper formatting of collection data and validation errors;
*
Proper formatting of collection data and validation errors;
*
Efficient routing with proper HTTP verb check;
*
Efficient routing with proper HTTP verb check;
*
Support
`OPTIONS`
and
`HEAD`
verbs;
*
Support
`OPTIONS`
and
`HEAD`
verbs;
*
Authentication
via HTTP basic
;
*
Authentication;
*
Authorization;
*
Authorization;
*
Caching via
`yii\web\HttpCache`
;
*
Caching via
`yii\web\HttpCache`
;
*
Support for HATEOAS: TBD
*
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.
...
@@ -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,
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.
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
`findIdentityBy
Access
Token()`
method.
It may look like the following:
It may look like the following:
```
php
```
php
class
User
extends
ActiveRecord
class
User
extends
ActiveRecord
{
{
...
...
public
static
function
findIdentityByToken
(
$token
)
public
static
function
findIdentityBy
Access
Token
(
$token
)
{
{
return
static
::
find
([
'a
pi_key
'
=>
$token
]);
return
static
::
find
([
'a
ccess_token
'
=>
$token
]);
}
}
}
}
```
```
This means your user table has a column named
`a
pi_key`
which stores API access key
s for the users.
This means your user table has a column named
`a
ccess_token`
which stores API access token
s for the users.
Pick up a
key
from the table as you will need it to access your APIs next.
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,
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:
...
@@ -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,
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:
which may give the following output:
...
@@ -108,7 +108,7 @@ Content-Type: application/json; charset=UTF-8
...
@@ -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
> 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.
> previously and leave the password field blank.
Try changing the acceptable content type to be
`application/xml`
, and you will see the result
Try changing the acceptable content type to be
`application/xml`
, and you will see the result
...
@@ -139,4 +139,57 @@ class User extends ActiveRecord
...
@@ -139,4 +139,57 @@ class User extends ActiveRecord
In the following subsections, we will explain in more details about implementing RESTful APIs.
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
-------
framework/rest/Controller.php
View file @
7a04dbaa
...
@@ -32,6 +32,14 @@ class Controller extends \yii\web\Controller
...
@@ -32,6 +32,14 @@ class Controller extends \yii\web\Controller
* The name of the header parameter representing the API version number.
* The name of the header parameter representing the API version number.
*/
*/
const
HEADER_VERSION
=
'version'
;
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.
* @var string|array the configuration for creating the serializer that formats the response data.
...
@@ -42,6 +50,14 @@ class Controller extends \yii\web\Controller
...
@@ -42,6 +50,14 @@ class Controller extends \yii\web\Controller
*/
*/
public
$enableCsrfValidation
=
false
;
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
* @var string the chosen API version number
* @see supportedVersions
* @see supportedVersions
*/
*/
...
@@ -150,15 +166,24 @@ class Controller extends \yii\web\Controller
...
@@ -150,15 +166,24 @@ class Controller extends \yii\web\Controller
/**
/**
* Authenticates the user.
* 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
* @throws UnauthorizedHttpException if the user is not authenticated successfully
*/
*/
protected
function
authenticate
()
protected
function
authenticate
()
{
{
$apiKey
=
Yii
::
$app
->
getRequest
()
->
getAuthUser
();
$request
=
Yii
::
$app
->
getRequest
();
if
(
$apiKey
===
null
||
!
Yii
::
$app
->
getUser
()
->
loginByToken
(
$apiKey
))
{
if
(
$this
->
authType
==
self
::
AUTH_TYPE_BASIC
)
{
Yii
::
$app
->
getResponse
()
->
getHeaders
()
->
set
(
'WWW-Authenticate'
,
'Basic realm="api"'
);
$accessToken
=
$request
->
getAuthUser
();
throw
new
UnauthorizedHttpException
(
$apiKey
===
null
?
'Please provide an API key.'
:
'You are requesting with an invalid API key.'
);
}
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.'
);
}
}
}
}
...
...
framework/web/IdentityInterface.php
View file @
7a04dbaa
...
@@ -58,7 +58,7 @@ interface IdentityInterface
...
@@ -58,7 +58,7 @@ interface IdentityInterface
* Null should be returned if such an identity cannot be found
* Null should be returned if such an identity cannot be found
* or the identity is not in an active state (disabled, deleted, etc.)
* or the identity is not in an active state (disabled, deleted, etc.)
*/
*/
public
static
function
findIdentityByToken
(
$token
);
public
static
function
findIdentityBy
Access
Token
(
$token
);
/**
/**
* Returns an ID that can uniquely identify a user identity.
* Returns an ID that can uniquely identify a user identity.
* @return string|integer an ID that uniquely identifies a user identity.
* @return string|integer an ID that uniquely identifies a user identity.
...
...
framework/web/User.php
View file @
7a04dbaa
...
@@ -213,7 +213,7 @@ class User extends Component
...
@@ -213,7 +213,7 @@ class User extends Component
{
{
/** @var IdentityInterface $class */
/** @var IdentityInterface $class */
$class
=
$this
->
identityClass
;
$class
=
$this
->
identityClass
;
$identity
=
$class
::
findIdentityByToken
(
$token
);
$identity
=
$class
::
findIdentityBy
Access
Token
(
$token
);
$this
->
setIdentity
(
$identity
);
$this
->
setIdentity
(
$identity
);
return
$identity
;
return
$identity
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment