168 lines
5.4 KiB
PHP
168 lines
5.4 KiB
PHP
<?php
|
|
namespace oauth;
|
|
|
|
use app\openapi\model\OAuthAccessTokenModel;
|
|
use app\openapi\model\OAuthAuthCodeModel;
|
|
use app\openapi\model\OAuthClientModel;
|
|
use app\openapi\model\OAuthRefreshTokenModel;
|
|
use OAuth2\IOAuth2GrantClient;
|
|
use OAuth2\IOAuth2GrantCode;
|
|
use OAuth2\IOAuth2RefreshTokens;
|
|
use OAuth2\Model\IOAuth2AccessToken;
|
|
use OAuth2\Model\IOAuth2AuthCode;
|
|
use OAuth2\Model\IOAuth2Client;
|
|
use OAuth2\Model\IOAuth2Token;
|
|
use OAuth2\Model\OAuth2AccessToken;
|
|
use OAuth2\Model\OAuth2AuthCode;
|
|
use OAuth2\Model\OAuth2Client;
|
|
use OAuth2\Model\OAuth2Token;
|
|
|
|
/**
|
|
* OAuth2存储实现
|
|
*/
|
|
class OAuthStorage implements IOAuth2GrantCode, IOAuth2RefreshTokens, IOAuth2GrantClient
|
|
{
|
|
private $salt = '';
|
|
|
|
public function __construct($salt = null)
|
|
{
|
|
if (!is_null($salt)) {
|
|
$this->salt = $salt;
|
|
}
|
|
}
|
|
|
|
public function addClient($client_id, $client_secret, $redirect_uri)
|
|
{
|
|
// 实现添加客户端的逻辑
|
|
$client = OAuthClientModel::create([
|
|
'client_id' => $client_id,
|
|
'client_secret' => hash('sha1', $client_id . $client_secret . $this->salt),
|
|
'redirect_uri' => $redirect_uri,
|
|
]);
|
|
|
|
return !$client->isEmpty();
|
|
}
|
|
|
|
public function getAuthCode($code): IOAuth2AuthCode
|
|
{
|
|
// 实现获取授权码的逻辑
|
|
$ret = OAuthAuthCodeModel::code($code)->find();
|
|
if (is_null($ret)) {
|
|
throw new \Exception('授权码不存在');
|
|
}
|
|
|
|
return new OAuth2AuthCode($ret->client_id, '', $ret->expires, $ret->scope, null, $ret->redirect_uri);
|
|
}
|
|
|
|
public function createAuthCode($code, $client_id, $user_id, $redirect_uri, $expires, $scope = null)
|
|
{
|
|
// 实现创建授权码的逻辑
|
|
$auth = OAuthAuthCodeModel::create([
|
|
'code' => $code,
|
|
'client_id' => $client_id,
|
|
'user_id' => $user_id,
|
|
'redirect_uri' => $redirect_uri,
|
|
'expires' => $expires,
|
|
'scope' => $scope,
|
|
]);
|
|
|
|
return !$auth->isEmpty();
|
|
}
|
|
|
|
public function markAuthCodeAsUsed($code)
|
|
{
|
|
// 实现标记授权码为已使用的逻辑
|
|
OAuthAuthCodeModel::code($code)->delete();
|
|
}
|
|
|
|
public function getClient($client_id): IOAuth2Client
|
|
{
|
|
// 实现获取客户端的逻辑
|
|
$ret = OAuthClientModel::clientId($client_id)->find();
|
|
if (is_null($ret)) {
|
|
throw new \Exception('客户端不存在');
|
|
}
|
|
if ($ret->enabled != 1) {
|
|
throw new \Exception('客户端已禁用');
|
|
}
|
|
|
|
return new OAuth2Client($ret->client_id, $ret->client_secret, [$ret->redirect_uri]);
|
|
}
|
|
|
|
public function checkClientCredentials(IOAuth2Client $client, $client_secret = null): bool
|
|
{
|
|
// 实现检查客户端凭证的逻辑
|
|
$client = OAuthClientModel::clientId($client->getPublicId())->find();
|
|
if (is_null($client)) {
|
|
return false;
|
|
}
|
|
|
|
return $client->client_secret == hash('sha1', $client->client_id . $client_secret . $this->salt);
|
|
}
|
|
|
|
public function getAccessToken($access_token): IOAuth2AccessToken
|
|
{
|
|
// 实现获取访问令牌的逻辑
|
|
$ret = OAuthAccessTokenModel::accessToken($access_token)->find();
|
|
if (is_null($ret)) {
|
|
throw new \Exception('访问令牌不存在');
|
|
}
|
|
|
|
return new OAuth2AccessToken($ret->client_id, $ret->access_token, $ret->expires, $ret->scope, null);
|
|
}
|
|
|
|
public function createAccessToken($access_token, IOAuth2Client $client, $user_id, $expires, $scope = null)
|
|
{
|
|
// 实现创建访问令牌的逻辑
|
|
OAuthAccessTokenModel::create([
|
|
'access_token' => $access_token,
|
|
'client_id' => $client->getPublicId(),
|
|
'user_id' => $user_id,
|
|
'expires' => $expires,
|
|
'scope' => $scope,
|
|
]);
|
|
}
|
|
|
|
public function checkClientCredentialsGrant(IOAuth2Client $client, $client_secret): array
|
|
{
|
|
// 实现检查受限授权类型的逻辑
|
|
return ['issue_refresh_token' => true];
|
|
}
|
|
|
|
public function checkRestrictedGrantType(IOAuth2Client $client, $grant_type): bool
|
|
{
|
|
// 实现检查受限授权类型的逻辑
|
|
return $grant_type == 'client_credentials' || $grant_type == 'refresh_token';
|
|
}
|
|
|
|
// IOAuth2RefreshTokens 接口方法实现
|
|
public function getRefreshToken($refresh_token): IOAuth2Token
|
|
{
|
|
// 实现获取刷新令牌的逻辑
|
|
$ret = OAuthRefreshTokenModel::refreshToken($refresh_token)->find();
|
|
if (is_null($ret)) {
|
|
throw new \Exception('刷新令牌不存在');
|
|
}
|
|
|
|
return new OAuth2Token($ret->client_id, $ret->refresh_token, $ret->expires, $ret->scope, null);
|
|
}
|
|
|
|
public function createRefreshToken($refresh_token, IOAuth2Client $client, $user_id, $expires, $scope = null)
|
|
{
|
|
// 实现创建刷新令牌的逻辑
|
|
OAuthRefreshTokenModel::create([
|
|
'refresh_token' => $refresh_token,
|
|
'client_id' => $client->getPublicId(),
|
|
'user_id' => $user_id,
|
|
'expires' => $expires,
|
|
'scope' => $scope,
|
|
]);
|
|
}
|
|
|
|
public function unsetRefreshToken($refresh_token)
|
|
{
|
|
// 实现注销刷新令牌的逻辑
|
|
OAuthRefreshTokenModel::refreshToken($refresh_token)->delete();
|
|
}
|
|
}
|