如何在 codeigniter 4 上获得 Header 授权?
How to get Header Authorization on code igniter 4?
我使用 code igniter 4 和 JWT 创建了 restful api。登录 API 工作正常并生成了身份验证令牌。但是我无法使用令牌获取登录详细信息,它在尝试获取授权令牌时显示错误(空值)。
public function details(){
$key = $this->getKey();
$authHeader = $this->request->getHeader("Authorization"); //return null
$authHeader = $authHeader->getValue(); //line 149 error, caused $authHeader is null
$token = $authHeader;
// $token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJUaGVfY2xhaW0iLCJhdWQiOiJUaGVfQXVkIiwiaWF0IjoxNjQxNTQ0MTQzLCJuYmYiOjE2NDE1NDQxNTMsImV4cCI6MTY0MTU0Nzc0MywiZGF0YSI6eyJpZCI6IjkiLCJhY2NvdW50X2lkIjoiY2ljY2NjIiwibmFtZSI6ImNvZGUgaWduaXRlciJ9fQ.TI3zztWxIYZxoa_vhTB04YoGMaq4GdD4bxzmrt8QAH0";
try{
$decoded = JWT::decode($token,$key,array("HS256"));
if($decoded){
$response = [
'status' => 200,
'error' => false,
'message' => 'Account details',
'data' => [
'account' => $decoded
]
];
return $this->respondCreated($response);
}
}catch(Exception $ex){
$response = [
'status' => 401,
'error' => true,
'message' =>'Access denied',
'data' => []
];
return $this->respondCreated($response);
}
}
邮递员的结果
{
"title": "Error",
"type": "Error",
"code": 500,
"message": "Call to a member function getValue() on null",
"file": "/var/www/html/project-root/app/Controllers/Account.php",
"line": 149,
"trace": [
{
"file": "/var/www/html/project-root/vendor/codeigniter4/framework/system/CodeIgniter.php",
"line": 825,
"function": "details",
"class": "App\Controllers\Account",
"type": "->",
"args": []
},
{
"file": "/var/www/html/project-root/vendor/codeigniter4/framework/system/CodeIgniter.php",
"line": 412,
"function": "runController",
"class": "CodeIgniter\CodeIgniter",
"type": "->",
"args": [
{}
]
},
{
"file": "/var/www/html/project-root/vendor/codeigniter4/framework/system/CodeIgniter.php",
"line": 320,
"function": "handleRequest",
"class": "CodeIgniter\CodeIgniter",
"type": "->",
"args": [
null,
{
"handler": "file",
"backupHandler": "dummy",
"storePath": "/var/www/html/project-root/writable/cache/",
"cacheQueryString": false,
"prefix": "",
"ttl": 60,
"reservedCharacters": "{}()/\@:",
"file": {
"storePath": "/var/www/html/project-root/writable/cache/",
"mode": 416
},
"memcached": {
"host": "127.0.0.1",
"port": 11211,
"weight": 1,
"raw": false
},
"redis": {
"host": "127.0.0.1",
"password": null,
"port": 6379,
"timeout": 0,
"database": 0
},
"validHandlers": {
"dummy": "CodeIgniter\Cache\Handlers\DummyHandler",
"file": "CodeIgniter\Cache\Handlers\FileHandler",
"memcached": "CodeIgniter\Cache\Handlers\MemcachedHandler",
"predis": "CodeIgniter\Cache\Handlers\PredisHandler",
"redis": "CodeIgniter\Cache\Handlers\RedisHandler",
"wincache": "CodeIgniter\Cache\Handlers\WincacheHandler"
}
},
false
]
},
{
"file": "/var/www/html/project-root/public/index.php",
"line": 35,
"function": "run",
"class": "CodeIgniter\CodeIgniter",
"type": "->",
"args": []
}
]
}
邮递员截图
如果我对令牌进行硬编码,我可以获得登录详细信息。为什么这一行 $authHeader = $this->request->getHeader("Authorization");
return 为空?
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/ [L]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
将此添加到您的 .htaccess
文件
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
然后像这样得到header
$this->request->getServer('HTTP_AUTHORIZATION')
更新
我注意到您没有使用 Authorization
选项卡,而是手动设置 header。如果您手动设置授权 header,请确保值字段以 Bearer
开头,例如
Bearer eyJ....
或者简单地使用授权选项卡和 select Bearer Token
以下是我为 header.
获取授权令牌的方式
在public/.htaccess 文件中我有如下配置:
# Disable directory browsing
Options All -Indexes
# ----------------------------------------------------------------------
# Rewrite engine
# ----------------------------------------------------------------------
# Turning on the rewrite engine is necessary for the following rules and features.
# FollowSymLinks must be enabled for this to work.
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
# If you installed CodeIgniter in a subfolder, you will need to
# change the following line to match the subfolder you need.
# http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
# RewriteBase /
# Redirect Trailing Slashes...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ / [L,R=301]
# Rewrite "www.example.com -> example.com"
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to the front controller, index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/ [L]
# Ensure Authorization header is passed along
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
ErrorDocument 404 index.php
</IfModule>
# Disable server signature start
ServerSignature Off
# Disable server signature end
并且在控制器中 apache_request_headers() 包装器用于获取 header。
$authorization = apache_request_headers()["Authorization"];
虽然这只适用于 Apache 服务器。
我使用 code igniter 4 和 JWT 创建了 restful api。登录 API 工作正常并生成了身份验证令牌。但是我无法使用令牌获取登录详细信息,它在尝试获取授权令牌时显示错误(空值)。
public function details(){
$key = $this->getKey();
$authHeader = $this->request->getHeader("Authorization"); //return null
$authHeader = $authHeader->getValue(); //line 149 error, caused $authHeader is null
$token = $authHeader;
// $token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJUaGVfY2xhaW0iLCJhdWQiOiJUaGVfQXVkIiwiaWF0IjoxNjQxNTQ0MTQzLCJuYmYiOjE2NDE1NDQxNTMsImV4cCI6MTY0MTU0Nzc0MywiZGF0YSI6eyJpZCI6IjkiLCJhY2NvdW50X2lkIjoiY2ljY2NjIiwibmFtZSI6ImNvZGUgaWduaXRlciJ9fQ.TI3zztWxIYZxoa_vhTB04YoGMaq4GdD4bxzmrt8QAH0";
try{
$decoded = JWT::decode($token,$key,array("HS256"));
if($decoded){
$response = [
'status' => 200,
'error' => false,
'message' => 'Account details',
'data' => [
'account' => $decoded
]
];
return $this->respondCreated($response);
}
}catch(Exception $ex){
$response = [
'status' => 401,
'error' => true,
'message' =>'Access denied',
'data' => []
];
return $this->respondCreated($response);
}
}
邮递员的结果
{
"title": "Error",
"type": "Error",
"code": 500,
"message": "Call to a member function getValue() on null",
"file": "/var/www/html/project-root/app/Controllers/Account.php",
"line": 149,
"trace": [
{
"file": "/var/www/html/project-root/vendor/codeigniter4/framework/system/CodeIgniter.php",
"line": 825,
"function": "details",
"class": "App\Controllers\Account",
"type": "->",
"args": []
},
{
"file": "/var/www/html/project-root/vendor/codeigniter4/framework/system/CodeIgniter.php",
"line": 412,
"function": "runController",
"class": "CodeIgniter\CodeIgniter",
"type": "->",
"args": [
{}
]
},
{
"file": "/var/www/html/project-root/vendor/codeigniter4/framework/system/CodeIgniter.php",
"line": 320,
"function": "handleRequest",
"class": "CodeIgniter\CodeIgniter",
"type": "->",
"args": [
null,
{
"handler": "file",
"backupHandler": "dummy",
"storePath": "/var/www/html/project-root/writable/cache/",
"cacheQueryString": false,
"prefix": "",
"ttl": 60,
"reservedCharacters": "{}()/\@:",
"file": {
"storePath": "/var/www/html/project-root/writable/cache/",
"mode": 416
},
"memcached": {
"host": "127.0.0.1",
"port": 11211,
"weight": 1,
"raw": false
},
"redis": {
"host": "127.0.0.1",
"password": null,
"port": 6379,
"timeout": 0,
"database": 0
},
"validHandlers": {
"dummy": "CodeIgniter\Cache\Handlers\DummyHandler",
"file": "CodeIgniter\Cache\Handlers\FileHandler",
"memcached": "CodeIgniter\Cache\Handlers\MemcachedHandler",
"predis": "CodeIgniter\Cache\Handlers\PredisHandler",
"redis": "CodeIgniter\Cache\Handlers\RedisHandler",
"wincache": "CodeIgniter\Cache\Handlers\WincacheHandler"
}
},
false
]
},
{
"file": "/var/www/html/project-root/public/index.php",
"line": 35,
"function": "run",
"class": "CodeIgniter\CodeIgniter",
"type": "->",
"args": []
}
]
}
邮递员截图
如果我对令牌进行硬编码,我可以获得登录详细信息。为什么这一行 $authHeader = $this->request->getHeader("Authorization");
return 为空?
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/ [L]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
将此添加到您的 .htaccess
文件
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
然后像这样得到header
$this->request->getServer('HTTP_AUTHORIZATION')
更新
我注意到您没有使用 Authorization
选项卡,而是手动设置 header。如果您手动设置授权 header,请确保值字段以 Bearer
开头,例如
Bearer eyJ....
或者简单地使用授权选项卡和 select Bearer Token
以下是我为 header.
获取授权令牌的方式在public/.htaccess 文件中我有如下配置:
# Disable directory browsing
Options All -Indexes
# ----------------------------------------------------------------------
# Rewrite engine
# ----------------------------------------------------------------------
# Turning on the rewrite engine is necessary for the following rules and features.
# FollowSymLinks must be enabled for this to work.
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
# If you installed CodeIgniter in a subfolder, you will need to
# change the following line to match the subfolder you need.
# http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
# RewriteBase /
# Redirect Trailing Slashes...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ / [L,R=301]
# Rewrite "www.example.com -> example.com"
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
# Checks to see if the user is attempting to access a valid file,
# such as an image or css document, if this isn't true it sends the
# request to the front controller, index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?/ [L]
# Ensure Authorization header is passed along
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
<IfModule !mod_rewrite.c>
# If we don't have mod_rewrite installed, all 404's
# can be sent to index.php, and everything works as normal.
ErrorDocument 404 index.php
</IfModule>
# Disable server signature start
ServerSignature Off
# Disable server signature end
并且在控制器中 apache_request_headers() 包装器用于获取 header。
$authorization = apache_request_headers()["Authorization"];
虽然这只适用于 Apache 服务器。