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
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Rotua Panjaitan
yii2
Commits
f7cf3b50
Commit
f7cf3b50
authored
Jan 13, 2015
by
Alexander Makarov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Guide on auth clients
parent
f07ccb0c
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
429 additions
and
47 deletions
+429
-47
README.md
docs/guide/README.md
+1
-1
security-auth-clients.md
docs/guide/security-auth-clients.md
+380
-3
README.md
extensions/authclient/README.md
+48
-43
No files found.
docs/guide/README.md
View file @
f7cf3b50
...
...
@@ -111,7 +111,7 @@ Security
*
[
Authentication
](
security-authentication.md
)
*
[
Authorization
](
security-authorization.md
)
*
[
Working with Passwords
](
security-passwords.md
)
*
**TBD**
[
Auth Clients
](
security-auth-clients.md
)
*
[
Auth Clients
](
security-auth-clients.md
)
*
[
Best Practices
](
security-best-practices.md
)
...
...
docs/guide/security-auth-clients.md
View file @
f7cf3b50
Auth Clients
============
> Note: This section is under development.
>
> It has no content yet.
Yii provides official extension that lets you authenticate and/or authorize using external services via consuming
[
OpenID
](
http://openid.net/
)
,
[
OAuth
](
http://oauth.net/
)
or
[
OAuth2
](
http://oauth.net/2/
)
.
Installing extension
--------------------
In order to install extension use Composer. Either run
```
composer require --prefer-dist yiisoft/yii2-authclient "*"
```
or add
```
json
"yiisoft/yii2-authclient"
:
"*"
```
to the
`require`
section of your composer.json.
Configuring clients
-------------------
After extension is installed you need to setup auth client collection application component:
```
php
'components'
=>
[
'authClientCollection'
=>
[
'class'
=>
'yii\authclient\Collection'
,
'clients'
=>
[
'google'
=>
[
'class'
=>
'yii\authclient\clients\GoogleOpenId'
],
'facebook'
=>
[
'class'
=>
'yii\authclient\clients\Facebook'
,
'clientId'
=>
'facebook_client_id'
,
'clientSecret'
=>
'facebook_client_secret'
,
],
// etc.
],
]
...
]
```
Out of the box the following clients are provided:
-
[
[\yii\authclient\clients\Facebook|Facebook
]
].
-
[
[yii\authclient\clients\GitHub|GitHub
]
].
-
Google (via
[
[yii\authclient\clients\GoogleOpenId|OpenID
]
] and
[
[yii\authclient\clients\GoogleOAuth|OAuth
]
]).
-
[
[yii\authclient\clients\LinkedIn|LinkedIn
]
].
-
[
[yii\authclient\clients\Live|Microsoft Live
]
].
-
[
[yii\authclient\clients\Twitter|Twitter
]
].
-
[
[yii\authclient\clients\VKontakte|VKontakte
]
].
-
Yandex (via
[
[yii\authclient\clients\YandexOpenId|OpenID
]
] and
[
[yii\authclient\clients\YandexOAuth|OAuth
]
]).
Configuration for each client is a bit different. For OAuth it's required to get client ID and secret key from
the service you're going to use. For OpenID it works out of the box in most cases.
Storing authorization data
--------------------------
In order to recognize the user authenticated via external service we need to store ID provided on first authentication
and then check against it on subsequent authentications. It's not a good idea to limit login options to external
services only since these may fail and there won't be a way for the user to log in. Instead it's better to provide
both external authentication and good old login and password.
If we're storing user information in a database the schema could be the following:
```
sql
CREATE
TABLE
user
(
id
int
(
11
)
NOT
NULL
AUTO_INCREMENT
PRIMARY
KEY
,
username
varchar
(
255
)
NOT
NULL
,
auth_key
varchar
(
32
)
NOT
NULL
,
password_hash
varchar
(
255
)
NOT
NULL
,
password_reset_token
varchar
(
255
),
email
varchar
(
255
)
NOT
NULL
,
status
smallint
(
6
)
NOT
NULL
DEFAULT
10
,
created_at
int
(
11
)
NOT
NULL
,
updated_at
int
(
11
)
NOT
NULL
);
CREATE
TABLE
auth
(
id
int
(
11
)
NOT
NULL
AUTO_INCREMENT
PRIMARY
KEY
,
user_id
int
(
11
)
NOT
NULL
,
source
string
(
255
)
NOT
NULL
,
source_id
string
(
255
)
NOT
NULL
);
ALTER
TABLE
auth
ADD
CONSTRAINT
fk
-
auth
-
user_id
-
user
-
id
FOREIGN
KEY
user_id
REFERENCES
auth
(
id
);
```
In the SQL above
`user`
is a standard table that is used in advanced application template to store user
info. Each user can authenticate using multiple external services therefore each
`user`
record can relate to
multiple
`auth`
records. In the
`auth`
table
`client_name`
is the name of the auth provider used and
`client_id`
is
unique user identificator that is provided by external service after successful login.
Using tables created above we can generate
`Auth`
model. No further adjustments needed.
Adding action to controller
---------------------------
Next step is to add
[
[yii\authclient\AuthAction
]
] to a web controller. Typically
`SiteController`
:
```
php
class
SiteController
extends
Controller
{
public
function
actions
()
{
return
[
'auth'
=>
[
'class'
=>
'yii\authclient\AuthAction'
,
'successCallback'
=>
[
$this
,
'onAuthSuccess'
],
],
];
}
public
function
onAuthSuccess
(
$client
)
{
$attributes
=
$client
->
getUserAttributes
();
/** @var Auth $auth */
$auth
=
Auth
::
find
()
->
where
([
'source'
=>
$client
->
getId
(),
'source_id'
=>
$attributes
[
'id'
],
])
->
one
();
if
(
Yii
::
$app
->
user
->
isGuest
)
{
if
(
$auth
)
{
// login
$user
=
$auth
->
user
;
Yii
::
$app
->
user
->
login
(
$user
);
}
else
{
// signup
if
(
User
::
find
()
->
where
([
'email'
=>
$attributes
[
'email'
]])
->
exists
())
{
Yii
::
$app
->
getSession
()
->
setFlash
(
'error'
,
[
Yii
::
t
(
'app'
,
"User with the same email as in
{
client
}
account already exists but isn't linked to it. Login using email first to link it."
,
[
'client'
=>
$client
->
getTitle
()]),
]);
}
else
{
$password
=
Yii
::
$app
->
security
->
generateRandomString
(
6
);
$user
=
new
User
([
'username'
=>
$attributes
[
'login'
],
'email'
=>
$attributes
[
'email'
],
'password'
=>
$password
,
]);
$user
->
generateAuthKey
();
$user
->
generatePasswordResetToken
();
$transaction
=
$user
->
getDb
()
->
beginTransaction
();
if
(
$user
->
save
())
{
$auth
=
new
Auth
([
'user_id'
=>
$user
->
id
,
'source'
=>
$client
->
getId
(),
'source_id'
=>
(
string
)
$attributes
[
'id'
],
]);
if
(
$auth
->
save
())
{
$transaction
->
commit
();
Yii
::
$app
->
user
->
login
(
$user
);
}
else
{
print_r
(
$auth
->
getErrors
());
}
}
else
{
print_r
(
$user
->
getErrors
());
}
}
}
}
else
{
// user already logged in
if
(
!
$auth
)
{
// add auth provider
$auth
=
new
Auth
([
'user_id'
=>
Yii
::
$app
->
user
->
id
,
'source'
=>
$client
->
getId
(),
'source_id'
=>
$attributes
[
'id'
],
]);
$auth
->
save
();
}
}
}
}
```
`successCallback`
method is called when user was successfully authenticated via external service. Via
`$client`
instance
we can retrieve information received. In our case we'd like to:
-
If user is guest and record found in auth then log this user in.
-
If user is logged in and record found in auth then try connecting additional account (save its data into auth table).
-
If user is guest and record not found in auth then create new user and make a record in auth table. Then log in.
Although, all clients are different they shares same basic interface
[
[yii\authclient\ClientInterface
]
],
which governs common API.
Each client has some descriptive data, which can be used for different purposes:
-
`id`
- unique client id, which separates it from other clients, it could be used in URLs, logs etc.
-
`name`
- external auth provider name, which this client is match too. Different auth clients
can share the same name, if they refer to the same external auth provider.
For example: clients for Google OpenID and Google OAuth have same name "google".
This attribute can be used inside the database, CSS styles and so on.
-
`title`
- user friendly name for the external auth provider, it is used to present auth client
at the view layer.
Each auth client has different auth flow, but all of them supports
`getUserAttributes()`
method,
which can be invoked if authentication was successful.
This method allows you to get information about external user account, such as ID, email address,
full name, preferred language etc.
Defining list of attributes, which external auth provider should return, depends on client type:
-
[
[yii\authclient\OpenId
]
]: combination of
`requiredAttributes`
and
`optionalAttributes`
.
-
[
[yii\authclient\OAuth1
]
] and
[
[yii\authclient\OAuth2
]
]: field
`scope`
, note that different
providers use different formats for the scope.
### Getting additional data via extra API calls
Both
[
[yii\authclient\OAuth1
]
] and
[
[yii\authclient\OAuth2
]
] provide method
`api()`
, which
can be used to access external auth provider REST API. However this method is very basic and
it may be not enough to access full external API functionality. This method is mainly used to
fetch the external user account data.
To use API calls, you need to setup
[
[yii\authclient\BaseOAuth::apiBaseUrl
]
] according to the
API specification. Then you can call
[
[yii\authclient\BaseOAuth::api()
]
] method:
```
php
use
yii\authclient\OAuth2
;
$client
=
new
OAuth2
;
// ...
$client
->
apiBaseUrl
=
'https://www.googleapis.com/oauth2/v1'
;
$userInfo
=
$client
->
api
(
'userinfo'
,
'GET'
);
```
Adding widget to login view
---------------------------
There's ready to use
[
[yii\authclient\widgets\AuthChoice
]
] widget to use in views:
```
php
<?=
yii\authclient\widgets\AuthChoice
::
widget
([
'baseAuthUrl'
=>
[
'site/auth'
],
'popupMode'
=>
false
,
])
?>
```
Creating your own auth clients
------------------------------
You may create your own auth client for any external auth provider, which supports
OpenId or OAuth protocol. To do so, first of all, you need to find out which protocol is
supported by the external auth provider, this will give you the name of the base class
for your extension:
-
For OAuth 2 use
[
[yii\authclient\OAuth2
]
].
-
For OAuth 1/1.0a use
[
[yii\authclient\OAuth1
]
].
-
For OpenID use
[
[yii\authclient\OpenId
]
].
At this stage you can determine auth client default name, title and view options, declaring
corresponding methods:
```
php
use
yii\authclient\OAuth2
;
class
MyAuthClient
extends
OAuth2
{
protected
function
defaultName
()
{
return
'my_auth_client'
;
}
protected
function
defaultTitle
()
{
return
'My Auth Client'
;
}
protected
function
defaultViewOptions
()
{
return
[
'popupWidth'
=>
800
,
'popupHeight'
=>
500
,
];
}
}
```
Depending on actual base class, you will need to redeclare different fields and methods.
### [[yii\authclient\OpenId]]
All you need is to specify auth URL, by redeclaring
`authUrl`
field.
You may also setup default required and/or optional attributes.
For example:
```
php
use
yii\authclient\OpenId
;
class
MyAuthClient
extends
OpenId
{
public
$authUrl
=
'https://www.my.com/openid/'
;
public
$requiredAttributes
=
[
'contact/email'
,
];
public
$optionalAttributes
=
[
'namePerson/first'
,
'namePerson/last'
,
];
}
```
### [[yii\authclient\OAuth2]]
You will need to specify:
-
Auth URL by redeclaring
`authUrl`
field.
-
Token request URL by redeclaring
`tokenUrl`
field.
-
API base URL by redeclaring
`apiBaseUrl`
field.
-
User attribute fetching strategy by redeclaring
`initUserAttributes()`
method.
For example:
```
php
use
yii\authclient\OAuth2
;
class
MyAuthClient
extends
OAuth2
{
public
$authUrl
=
'https://www.my.com/oauth2/auth'
;
public
$tokenUrl
=
'https://www.my.com/oauth2/token'
;
public
$apiBaseUrl
=
'https://www.my.com/apis/oauth2/v1'
;
protected
function
initUserAttributes
()
{
return
$this
->
api
(
'userinfo'
,
'GET'
);
}
}
```
You may also specify default auth scopes.
> Note: Some OAuth providers may not follow OAuth standards clearly, introducing
differences, and may require additional efforts to implement clients for.
### [[yii\authclient\OAuth1]]
You will need to specify:
-
Auth URL by redeclaring
`authUrl`
field.
-
Request token URL by redeclaring
`requestTokenUrl`
field.
-
Access token URL by redeclaring
`accessTokenUrl`
field.
-
API base URL by redeclaring
`apiBaseUrl`
field.
-
User attribute fetching strategy by redeclaring
`initUserAttributes()`
method.
For example:
```
php
use
yii\authclient\OAuth1
;
class
MyAuthClient
extends
OAuth1
{
public
$authUrl
=
'https://www.my.com/oauth/auth'
;
public
$requestTokenUrl
=
'https://www.my.com/oauth/request_token'
;
public
$accessTokenUrl
=
'https://www.my.com/oauth/access_token'
;
public
$apiBaseUrl
=
'https://www.my.com/apis/oauth/v1'
;
protected
function
initUserAttributes
()
{
return
$this
->
api
(
'userinfo'
,
'GET'
);
}
}
```
You may also specify default auth scopes.
> Note: Some OAuth providers may not follow OAuth standards clearly, introducing
differences, and may require additional efforts to implement clients for.
extensions/authclient/README.md
View file @
f7cf3b50
AuthClient Extension for Yii 2
==============================
This extension adds
[
OpenID
](
http://openid.net/
)
,
[
OAuth
](
http://oauth.net/
)
and
[
OAuth2
](
http://oauth.net/2/
)
consumers for the Yii framework 2.0.
This extension adds
[
OpenID
](
http://openid.net/
)
,
[
OAuth
](
http://oauth.net/
)
and
[
OAuth2
](
http://oauth.net/2/
)
consumers
for the Yii framework 2.0.
Installation
...
...
@@ -12,7 +13,7 @@ The preferred way to install this extension is through [composer](http://getcomp
Either run
```
php composer.pha
r require --prefer-dist yiisoft/yii2-authclient "*"
compose
r require --prefer-dist yiisoft/yii2-authclient "*"
```
or add
...
...
@@ -51,7 +52,7 @@ You need to setup auth client collection application component:
]
```
Then you need to add
[
[yii\authclient\AuthAction
]
] to
some of your web controllers
:
Then you need to add
[
[yii\authclient\AuthAction
]
] to
web controller
:
```
php
class
SiteController
extends
Controller
...
...
@@ -100,33 +101,33 @@ Although, all clients are different they shares same basic interface [[yii\authc
which governs some common API.
Each client has some descriptive data, which can be used for different purposes:
-
id
- unique client id, which separates it from other clients, it could be used in URLs, logs etc.
-
name
- external auth provider name, which this client is match too. Different auth clients
-
`id`
- unique client id, which separates it from other clients, it could be used in URLs, logs etc.
-
`name`
- external auth provider name, which this client is match too. Different auth clients
can share the same name, if they refer to the same external auth provider.
For example: clients for Google OpenID and Google OAuth have same name "google".
This attribute can be used inside the database, CSS styles and so on.
-
title
- user friendly name for the external auth provider, it is used to present auth client
-
`title`
- user friendly name for the external auth provider, it is used to present auth client
at the view layer.
Each auth client has different auth flow, but all of them supports
"getUserAttributes()"
method,
Each auth client has different auth flow, but all of them supports
`getUserAttributes()`
method,
which can be invoked if authentication was successful.
This method allows you to get information about external user account, such as id, email address,
full name, preferred language etc.
Defining list of attributes, which external auth provider should return, depends on client type:
-
[
[yii\authclient\OpenId
]
]: combination of
"requiredAttributes" and "optionalAttributes"
-
[
[yii\authclient\OAuth1
]
] and
[
[yii\authclient\OAuth2
]
]: field
"scope"
, note that different
-
[
[yii\authclient\OpenId
]
]: combination of
`requiredAttributes`
and
`optionalAttributes`
-
[
[yii\authclient\OAuth1
]
] and
[
[yii\authclient\OAuth2
]
]: field
`scope`
, note that different
providers use different formats for the scope.
Each auth client has
"viewOptions"
attribute. It is an array, which stores name-value pairs,
Each auth client has
`viewOptions`
attribute. It is an array, which stores name-value pairs,
which serve to compose client representation in the view.
For example widget
[
[yii\authclient\widgets\AuthChoice
]
] uses keys
"popupWidth" and "popupHeight"
to
For example widget
[
[yii\authclient\widgets\AuthChoice
]
] uses keys
`popupWidth`
and
`popupHeight`
to
determine the size of authentication popup window.
External API usage
------------------
Both
[
[yii\authclient\OAuth1
]
] and
[
[yii\authclient\OAuth2
]
] provide method
"api()"
, which
Both
[
[yii\authclient\OAuth1
]
] and
[
[yii\authclient\OAuth2
]
] provide method
`api()`
, which
can be used to access external auth provider REST API. However this method is very basic and
it may be not enough to access full external API functionality. This method is mainly used to
fetch the external user account data.
...
...
@@ -147,20 +148,20 @@ Predefined auth clients
-----------------------
This extension provides the list of ready to use auth clients, which covers most
popular external authentication providers. These clients are located under
"yii
\a
uthclient
\c
lients"
popular external authentication providers. These clients are located under
`yii\authclient\clients`
namespace.
Following predefined auth clients are available:
-
[
[yii\authclient\clients\Facebook
]
] -
[
Facebook
](
https://www.facebook.com/
)
OAuth2 client
-
[
[yii\authclient\clients\GitHub
]
] -
[
GitHub
](
https://github.com/
)
OAuth2 client
-
[
[yii\authclient\clients\GoogleOAuth
]
] -
[
Google
](
https://www.google.com/
)
OAuth2 client
-
[
[yii\authclient\clients\GoogleOpenId
]
] -
[
Google
](
https://www.google.com/
)
OpenID client
-
[
[yii\authclient\clients\LinkedIn
]
] -
[
LinkedIn
](
http://www.linkedin.com/
)
OAuth2 client
-
[
[yii\authclient\clients\Live
]
] -
[
Microsoft Live
](
http://live.com/
)
OAuth2 client
-
[
[yii\authclient\clients\Twitter
]
] -
[
Twitter
](
https://twitter.com/
)
OAuth1 client
-
[
[yii\authclient\clients\VKontakte
]
] -
[
VKontakte
](
http://vk.com/
)
OAuth2 client
-
[
[yii\authclient\clients\YandexOAuth
]
] -
[
Yandex
](
http://www.yandex.ru/
)
OAuth2 client
-
[
[yii\authclient\clients\YandexOpenId
]
] -
[
Yandex
](
http://www.yandex.ru/
)
OpenID client
-
[
[yii\authclient\clients\Facebook
]
] -
[
Facebook
](
https://www.facebook.com/
)
OAuth2 client
.
-
[
[yii\authclient\clients\GitHub
]
] -
[
GitHub
](
https://github.com/
)
OAuth2 client
.
-
[
[yii\authclient\clients\GoogleOAuth
]
] -
[
Google
](
https://www.google.com/
)
OAuth2 client
.
-
[
[yii\authclient\clients\GoogleOpenId
]
] -
[
Google
](
https://www.google.com/
)
OpenID client
.
-
[
[yii\authclient\clients\LinkedIn
]
] -
[
LinkedIn
](
http://www.linkedin.com/
)
OAuth2 client
.
-
[
[yii\authclient\clients\Live
]
] -
[
Microsoft Live
](
http://live.com/
)
OAuth2 client
.
-
[
[yii\authclient\clients\Twitter
]
] -
[
Twitter
](
https://twitter.com/
)
OAuth1 client
.
-
[
[yii\authclient\clients\VKontakte
]
] -
[
VKontakte
](
http://vk.com/
)
OAuth2 client
.
-
[
[yii\authclient\clients\YandexOAuth
]
] -
[
Yandex
](
http://www.yandex.ru/
)
OAuth2 client
.
-
[
[yii\authclient\clients\YandexOpenId
]
] -
[
Yandex
](
http://www.yandex.ru/
)
OpenID client
.
Please, refer to the particular client class documentation for its actual usage.
...
...
@@ -199,9 +200,10 @@ You may create your own auth client for any external auth provider, which suppor
OpenId or OAuth protocol. To do so, first of all, you need to find out which protocol is
supported by the external auth provider, this will give you the name of the base class
for your extension:
-
for OAuth 2 use
[
[yii\authclient\OAuth2
]
]
-
for OAuth 1/1.0a use
[
[yii\authclient\OAuth1
]
]
-
for OpenID use
[
[yii\authclient\OpenId
]
]
-
For OAuth 2 use
[
[yii\authclient\OAuth2
]
].
-
For OAuth 1/1.0a use
[
[yii\authclient\OAuth1
]
].
-
For OpenID use
[
[yii\authclient\OpenId
]
].
At this stage you can determine auth client default name, title and view options, declaring
corresponding methods:
...
...
@@ -233,9 +235,9 @@ class MyAuthClient extends OAuth2
Depending on actual base class, you will need to redeclare different fields and methods.
1)
[
[yii\authclient\OpenId
]
]
###
[[yii\authclient\OpenId]]
All you need is
specify auth URL, by redeclaring "authUrl"
field.
All you need is
to specify auth URL, by redeclaring
`authUrl`
field.
You may also setup default required and/or optional attributes.
For example:
...
...
@@ -257,13 +259,14 @@ class MyAuthClient extends OpenId
}
```
2)
[
[yii\authclient\OAuth2
]
]
###
[[yii\authclient\OAuth2]]
You will need to specify:
-
authorize URL - redeclare "authUrl" field
-
token request URL - redeclare "tokenUrl" field
-
API base URL - redeclare "apiBaseUrl" field
-
User attribute fetching strategy - redeclare "initUserAttributes" method
-
Auth URL by redeclaring
`authUrl`
field.
-
Token request URL by redeclaring
`tokenUrl`
field.
-
API base URL by redeclaring
`apiBaseUrl`
field.
-
User attribute fetching strategy by redeclaring
`initUserAttributes()`
method.
For example:
...
...
@@ -287,17 +290,18 @@ class MyAuthClient extends OAuth2
You may also specify default auth scopes.
Note: s
ome OAuth providers may not follow OAuth standards clearly, introducing
some differences, which may require additional efforts to apply
.
> Note: S
ome OAuth providers may not follow OAuth standards clearly, introducing
differences, and may require additional efforts to implement clients for
.
3)
[
[yii\authclient\OAuth1
]
]
###
[[yii\authclient\OAuth1]]
You will need to specify:
-
authorize URL - redeclare "authUrl" field
-
request token URL - redeclare "requestTokenUrl" field
-
access token URL - redeclare "accessTokenUrl" field
-
API base URL - redeclare "apiBaseUrl" field
-
User attribute fetching strategy - redeclare "initUserAttributes" method
-
Auth URL by redeclaring
`authUrl`
field.
-
Request token URL by redeclaring
`requestTokenUrl`
field.
-
Access token URL by redeclaring
`accessTokenUrl`
field.
-
API base URL by redeclaring
`apiBaseUrl`
field.
-
User attribute fetching strategy by redeclaring
`initUserAttributes()`
method.
For example:
...
...
@@ -323,5 +327,6 @@ class MyAuthClient extends OAuth1
You may also specify default auth scopes.
Note: some OAuth providers may not follow OAuth standards clearly, introducing
some differences, which may require additional efforts to apply.
> Note: Some OAuth providers may not follow OAuth standards clearly, introducing
differences, and may require additional efforts to implement clients for.
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