रिकॉर्ड के लिए, मैं पीएचपीएसटॉर्म के साथ एक वाग्रेंट बॉक्स में PHP 7.0.0 का उपयोग कर रहा हूं। ओह, और सिम्फनी 3.सिम्फनी - एपीआई टोकन के साथ प्रमाणीकरण - अनुरोध टोकन उपयोगकर्ता शून्य
मैं API Key Authentication दस्तावेज़ीकरण का पालन कर रहा हूं। मेरा लक्ष्य है:
- जाहिर
- डेवलपर एक नियंत्रक में
$request->getUser()
लिखने के लिए अनुमति देने के लिए डेवलपर प्रोफाइलर आदि को छोड़कर उपयोगकर्ता किसी भी मार्ग के लिए प्रमाणित करने के लिए एक प्राप्तapiKey
पैरामीटर के रूप में एक महत्वपूर्ण प्रदान करने के लिए अनुमति देने के लिए, वर्तमान में उपयोगकर्ता के प्रवेश करने के लिए
मेरे समस्या यह है कि, हालांकि मेरा मानना है कि मैं पत्र के लिए प्रलेखन का पालन किया है, मैं अभी भी एक null
नियंत्रक में $request->getUser()
के लिए हो रही है है।
नोट: मैं त्रुटि कोड लघु
ApiKeyAuthenticator.php
बात यह है कि अनुरोध इसे से API कुंजी हड़पने के लिए के हिस्से को संसाधित करता है रखने के लिए जाँच हटा दिया है । यह एक हेडर या कुछ भी हो सकता है, लेकिन मैं GET से
apiKey
के साथ चिपक रहा हूं। दस्तावेज़ से
मतभेद, काफी 0 अलग है कि मैं उपयोगकर्ता निम्न दस्तावेज़ों की this part सत्र में प्रमाणीकृत रखने के लिए कोशिश कर रहा हूँ से। मैं डिफ़ॉल्ट डीबी कार्यान्वयन के साथ चिपके हुए कर रहा हूँ -
class ApiKeyAuthenticator implements SimplePreAuthenticatorInterface
{
public function createToken(Request $request, $providerKey)
{
$apiKey = $request->query->get('apiKey');
return new PreAuthenticatedToken(
'anon.',
$apiKey,
$providerKey
);
}
public function authenticateToken(TokenInterface $token, UserProviderInterface $userProvider, $providerKey)
{
$apiKey = $token->getCredentials();
$username = $userProvider->getUsernameForApiKey($apiKey);
// The part where we try and keep the user in the session!
$user = $token->getUser();
if ($user instanceof ApiKeyUser) {
return new PreAuthenticatedToken(
$user,
$apiKey,
$providerKey,
$user->getRoles()
);
}
$user = $userProvider->loadUserByUsername($username);
return new PreAuthenticatedToken(
$user,
$apiKey,
$providerKey,
$user->getRoles()
);
}
public function supportsToken(TokenInterface $token, $providerKey)
{
return $token instanceof PreAuthenticatedToken && $token->getProviderKey() === $providerKey;
}
}
ApiKeyUserProvider.php
कस्टम उपयोगकर्ता प्रदाता कहीं से लोड किया जा सकता से एक उपयोगकर्ता वस्तु लोड करने के लिए।
अंतर: केवल तथ्य यह है मैं, निर्माता में भंडार सुई डीबी के लिए कॉल करने के लिए है कि के रूप में किए गए दस्तावेज़ों का उल्लेख करने लेकिन नहीं दिखा, और भी refreshUser()
में $user
लौटने।
class ApiKeyUserProvider implements UserProviderInterface
{
protected $repo;
// I'm injecting the Repo here (docs don't help with this)
public function __construct(UserRepository $repo)
{
$this->repo = $repo;
}
public function getUsernameForApiKey($apiKey)
{
$data = $this->repo->findUsernameByApiKey($apiKey);
$username = (!is_null($data)) ? $data->getUsername() : null;
return $username;
}
public function loadUserByUsername($username)
{
return $this->repo->findOneBy(['username' => $username]);
}
public function refreshUser(UserInterface $user)
{
// docs state to return here if we don't want stateless
return $user;
}
public function supportsClass($class)
{
return 'Symfony\Component\Security\Core\User\User' === $class;
}
}
ApiKeyUser.php
यह मेरा कस्टम उपयोगकर्ता वस्तु है।
मेरे यहां एकमात्र अंतर यह है कि इसमें सिद्धांत एनोटेशन (आपकी सैनिटी के लिए हटाया गया) और टोकन के लिए एक कस्टम फ़ील्ड शामिल है। इसके अलावा, मैंने \Serializable
हटा दिया क्योंकि ऐसा कुछ नहीं लगता था और स्पष्ट रूप से सिम्फनी को उपयोगकर्ता को फिर से बनाने के लिए $id
मान की आवश्यकता होती है।
class ApiKeyUser implements UserInterface
{
private $id;
private $username;
private $password;
private $email;
private $salt;
private $apiKey;
private $isActive;
public function __construct($username, $password, $salt, $apiKey, $isActive = true)
{
$this->username = $username;
$this->password = $password;
$this->salt = $salt;
$this->apiKey = $apiKey;
$this->isActive = $isActive;
}
//-- SNIP getters --//
}
security.yml
# Here is my custom user provider class from above
providers:
api_key_user_provider:
id: api_key_user_provider
firewalls:
# Authentication disabled for dev (default settings)
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
# My new settings, with stateless set to false
secured_area:
pattern: ^/
stateless: false
simple_preauth:
authenticator: apikey_authenticator
provider:
api_key_user_provider
services.yml
जाहिर है मैं प्रदाता में भंडार इंजेक्षन करने में सक्षम होने की जरूरत है।
api_key_user_repository:
class: Doctrine\ORM\EntityRepository
factory: ["@doctrine.orm.entity_manager", getRepository]
arguments: [AppBundle\Security\ApiKeyUser]
api_key_user_provider:
class: AppBundle\Security\ApiKeyUserProvider
factory_service: doctrine.orm.default_entity_manager
factory_method: getRepository
arguments: ["@api_key_user_repository"]
apikey_authenticator:
class: AppBundle\Security\ApiKeyAuthenticator
public: false
डिबगिंग। यह ध्यान रखना दिलचस्प है कि, ApiKeyAuthenticator.php
में, $user = $token->getUser();
पर authenticateToken()
पर कॉल हमेशा anon.
उपयोगकर्ता दिखाता है, इसलिए यह स्पष्ट रूप से सत्र में संग्रहीत नहीं किया जा रहा है।
यह भी ध्यान रखें कि कैसे प्रमाणक के निचले भाग में हम वास्तव में एक उपयोगकर्ता डेटाबेस से पाया के साथ एक नया PreAuthenticatedToken
वापसी करते हैं:
तो यह स्पष्ट रूप से पाया मैं और यह लौट रहा हूं कि इसे यहां क्या माना जाता है, लेकिन नियंत्रक में उपयोगकर्ता कॉल null
देता है। मैं क्या गलत कर रहा हूं? क्या यह मेरे कस्टम उपयोगकर्ता या कुछ के कारण सत्र में क्रमबद्ध करने में विफलता है? मैंने दस्तावेज में कहीं भी सभी उपयोगकर्ता गुणों को सार्वजनिक रूप से सेट करने का प्रयास किया लेकिन इससे कोई फर्क नहीं पड़ता।
आप इस परीक्षण करने की कोशिश कर सकते हैं, अपने फ़ायरवॉल में जोड़ें: 'access_control: - {पथ:^/, भूमिकाओं: IS_AUTHENTICATED_ANONYMOUSLY}' – COil
मैं इस 'security.yml में' security' के तहत एक कुंजी के रूप में जोड़ा '। कोई परिवर्तन नहीं होता है। – Jimbo
क्या आप अपनी सभी संपत्तियों को ApiKeyUser क्लास में संरक्षित के रूप में सेट करके आजमा सकते हैं? – hasumedic