Pez*_*Pez 12 symfony fosuserbundle fosrestbundle hwioauthbundle
编辑:请参阅下面的我自己的解决方案,在撰写本文时,它正在运作但不完美.我会喜欢一些批评和反馈,如果我把一些我觉得非常可靠的东西放在一起,那么我会为面临同样挑战的其他人制作一篇howto博客文章.
几天来我一直在努力奋斗,如果我走在正确的道路上,我希望有人能告诉我.
我有一个带有FOSRestBundle webservice的系统,我正在使用FOSUserBundle和HWIOAuthBundle来验证用户.
我想为webservice设置无状态api密钥身份验证.
我已经阅读了http://symfony.com/doc/current/cookbook/security/api_key_authentication.html,这看起来很简单,我已经安装了UecodeApiKeyBundle,这似乎只是本书页面的一个实现.
我的问题是n00b ...现在怎么样?书籍页面和包都涵盖了通过API密钥对用户进行身份验证,但不涉及日志用户流,生成API密钥,允许用户注册等.我真正想要的是用于登录的简单API端点,注册,以及我的应用开发者可以使用的注销.像/ api/v1/login等等.
我想我可以处理注册....虽然登录让我感到困惑.根据一些额外的阅读,在我看来,我需要做的登录是这样的:
在api/v1/login创建一个接受POST请求的控制器.请求看起来像{_username:foo,_ password:bar}或类似{facebook_access_token:foo.或者,facebook登录可能需要不同的操作,例如/ user/login/facebook,并且只需重定向到HWIOAuthBundle路径}.
如果请求包含_username和_password参数,那么我需要将请求转发到login-check(我不确定这个.我可以自己处理这个表单吗?或者,我应该手动检查用户名和密码数据库?)
添加一个登录事件监听器,如果用户认证成功,则为用户生成一个api密钥(当然,如果我自己没有检查它,这是必要的)
在POST请求的响应中返回API密钥(这会打破post-redirect-get策略,但是我没有看到任何问题)我认为这消除了上面列出的重定向登录检查选项.
你可能会看到我很困惑.这是我的第一个Symfony2项目,关于安全的书页很简单......但似乎掩盖了一些细节,这使我不确定要采取的方法.
提前致谢!
================================================== ===========
编辑:
我已经安装了API密钥身份验证,与相关的相关菜谱文章完全相同:http://symfony.com/doc/current/cookbook/security/api_key_authentication.html
为了处理用户的登录,我创建了一个自定义控制器方法.我怀疑这是完美的,我很乐意听到一些关于如何改进它的反馈,但我相信我正走在正确的道路上,因为我的流程正在发挥作用.这是代码(请注意,还在开发的早期......我还没有看过Facebook登录,只有简单的用户名/密码登录):
class SecurityController extends FOSRestController
{
/**
* Create a security token for the user
*/
public function tokenCreateAction()
{
$request = $this->getRequest();
$username = $request->get('username',NULL);
$password = $request->get('password',NULL);
if (!isset($username) || !isset($password)){
throw new BadRequestHttpException("You must pass username and password fields");
}
$um = $this->get('fos_user.user_manager');
$user = $um->findUserByUsernameOrEmail($username);
if (!$user instanceof \Acme\UserBundle\Entity\User) {
throw new AccessDeniedHttpException("No matching user account found");
}
$encoder_service = $this->get('security.encoder_factory');
$encoder = $encoder_service->getEncoder($user);
$encoded_pass = $encoder->encodePassword($password, $user->getSalt());
if ($encoded_pass != $user->getPassword()) {
throw new AccessDeniedHttpException("Password does not match password on record");
}
//User checks out, generate an api key
$user->generateApiKey();
$em = $this->getDoctrine()->getEntityManager();
$em->persist($user);
$em->flush();
return array("apiKey" => $user->getApiKey());
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎工作得很好,用户注册将以类似方式处理.
有趣的是,我从cookbook实现的api密钥验证方法似乎忽略了我的security.yml文件中的access_control设置,在cookbook中他们概述了如何仅生成特定路径的令牌,但我不喜欢解决方案,所以我实现了自己的(也有点差)解决方案,不检查我用来验证用户的路径
api_login:
pattern: ^/api/v1/user/authenticate$
security: false
api:
pattern: ^/api/*
stateless: true
anonymous: true
simple_preauth:
authenticator: apikey_authenticator
Run Code Online (Sandbox Code Playgroud)
我确信有更好的方法可以做到这一点,但是再次......不确定它是什么.
我认为您实际上并不真正需要 /login 端点。
在 symfony 文档中,API 客户端需要将其密钥(通过 apiKey http 参数)传递给 API 的每个请求。
我不确定这是否是最佳实践,但你可以这样做。
"The book page and bundle both cover authenticating a user by API key, but don't touch on the flow of logging users in, generating API keys, allowing users to register"
Run Code Online (Sandbox Code Playgroud)
最好的方法是允许您的用户通过网络表单进行注册(例如使用路线 fos_user_register)。用户实体可以有一个 apikey 字段,预先填充了像 sha1("secret".time()) 这样生成的密钥,并且在其配置文件中有一个用于重新生成密钥的按钮。
| 归档时间: |
|
| 查看次数: |
7968 次 |
| 最近记录: |