Completed
Push — master ( 5a9669...ea2c47 )
by Dmitry
12:22
created

HttpBasicAuth::authenticate()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 7

Importance

Changes 0
Metric Value
dl 0
loc 26
ccs 15
cts 15
cp 1
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 16
nc 6
nop 3
crap 7
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\filters\auth;
9
10
use yii\web\Request;
11
12
/**
13
 * HttpBasicAuth is an action filter that supports the HTTP Basic authentication method.
14
 *
15
 * You may use HttpBasicAuth by attaching it as a behavior to a controller or module, like the following:
16
 *
17
 * ```php
18
 * public function behaviors()
19
 * {
20
 *     return [
21
 *         'basicAuth' => [
22
 *             'class' => \yii\filters\auth\HttpBasicAuth::className(),
23
 *         ],
24
 *     ];
25
 * }
26
 * ```
27
 *
28
 * The default implementation of HttpBasicAuth uses the [[\yii\web\User::loginByAccessToken()|loginByAccessToken()]]
29
 * method of the `user` application component and only passes the user name. This implementation is used
30
 * for authenticating API clients.
31
 *
32
 * If you want to authenticate users using username and password, you should provide the [[auth]] function for example like the following:
33
 *
34
 * ```php
35
 * public function behaviors()
36
 * {
37
 *     return [
38
 *         'basicAuth' => [
39
 *             'class' => \yii\filters\auth\HttpBasicAuth::className(),
40
 *             'auth' => function ($username, $password) {
41
 *                 $user = User::find()->where(['username' => $username])->one();
42
 *                 if ($user->verifyPassword($password)) {
43
 *                     return $user;
44
 *                 }
45
 *                 return null;
46
 *             },
47
 *         ],
48
 *     ];
49
 * }
50
 * ```
51
 *
52
 * > Tip: In case authentication does not work like expected, make sure your web server passes
53
 * username and password to `$_SERVER['PHP_AUTH_USER']` and `$_SERVER['PHP_AUTH_PW']` variables.
54
 * If you are using Apache with PHP-CGI, you might need to add this line to your `.htaccess` file:
55
 * ```
56
 * RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
57
 * ```
58
 *
59
 * @author Qiang Xue <[email protected]>
60
 * @since 2.0
61
 */
62
class HttpBasicAuth extends AuthMethod
63
{
64
    /**
65
     * @var string the HTTP authentication realm
66
     */
67
    public $realm = 'api';
68
    /**
69
     * @var callable a PHP callable that will authenticate the user with the HTTP basic auth information.
70
     * The callable receives a username and a password as its parameters. It should return an identity object
71
     * that matches the username and password. Null should be returned if there is no such identity.
72
     *
73
     * The following code is a typical implementation of this callable:
74
     *
75
     * ```php
76
     * function ($username, $password) {
77
     *     return \app\models\User::findOne([
78
     *         'username' => $username,
79
     *         'password' => $password,
80
     *     ]);
81
     * }
82
     * ```
83
     *
84
     * If this property is not set, the username information will be considered as an access token
85
     * while the password information will be ignored. The [[\yii\web\User::loginByAccessToken()]]
86
     * method will be called to authenticate and login the user.
87
     */
88
    public $auth;
89
90
91
    /**
92
     * @inheritdoc
93
     */
94 20
    public function authenticate($user, $request, $response)
95
    {
96 20
        list($username, $password) = $request->getAuthCredentials();
97
98 20
        if ($this->auth) {
99 5
            if ($username !== null || $password !== null) {
100 5
                $identity = call_user_func($this->auth, $username, $password);
101 5
                if ($identity !== null) {
102 3
                    $user->switchIdentity($identity);
103
                } else {
104 2
                    $this->handleFailure($response);
105
                }
106
107 3
                return $identity;
108
            }
109 15
        } elseif ($username !== null) {
110 12
            $identity = $user->loginByAccessToken($username, get_class($this));
111 12
            if ($identity === null) {
112 3
                $this->handleFailure($response);
113
            }
114
115 9
            return $identity;
116
        }
117
118 3
        return null;
119
    }
120
121
    /**
122
     * @inheritdoc
123
     */
124 3
    public function challenge($response)
125
    {
126 3
        $response->getHeaders()->set('WWW-Authenticate', "Basic realm=\"{$this->realm}\"");
127 3
    }
128
}
129