我有一个FOSUserBundle项目。并且需要添加OAuth支持。所以我安装了HWIOAuthBundle,并配置如此https://gist.github.com/danvbe/4476697和https://github.com/hwi/HWIOAuthBundle/blob/master/Resources/doc/bonus/facebook-connect.md,但是当我正在尝试登录时,返回我的错误凭据。我做错了什么?
我的security.yml
security:
encoders:
FOS\UserBundle\Model\UserInterface: sha512
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_USER
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_provider: form.csrf_provider
login_path: /login
check_path: /login_check
oauth:
resource_owners:
facebook: /security/check-facebook
login_path: /security
use_forward: false
failure_path: /security
oauth_user_provider:
service: my_user_provider
logout: true
anonymous: true
login:
pattern: ^/login$
security: false
remember_me:
key: "%secret%"
lifetime: 31536000
path: /
domain: ~
access_control:
- { path: ^/redirect.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/security.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/connect.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
的routing.yml
app:
resource: "@AppBundle/Controller/"
type: annotation
fos_user_security:
resource: "@FOSUserBundle/Resources/config/routing/security.xml"
fos_user_profile:
resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
prefix: /profile
fos_user_register:
resource: "@FOSUserBundle/Resources/config/routing/registration.xml"
prefix: /register
fos_user_resetting:
resource: "@FOSUserBundle/Resources/config/routing/resetting.xml"
prefix: /resetting
fos_user_change_password:
resource: "@FOSUserBundle/Resources/config/routing/change_password.xml"
prefix: /profile
fos_js_routing:
resource: "@FOSJsRoutingBundle/Resources/config/routing/routing.xml"
hwi_oauth_redirect:
resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /redirect
hwi_oauth_security:
resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
prefix: /security
hwi_oauth_connect:
resource: "@HWIOAuthBundle/Resources/config/routing/connect.xml"
prefix: /connect
facebook_login:
pattern: /security/check-facebook
config.yml
fos_user:
db_driver: orm
firewall_name: main
user_class: AppBundle\Entity\User
registration:
form:
type: test_chat_user_registration
hwi_oauth:
connect:
account_connector: my_user_provider
firewall_name: main
fosub:
username_iterations: 30
properties:
facebook: facebookId
resource_owners:
facebook:
type: facebook
client_id: "%facebook_id%"
client_secret: "%facebook_access_token%%"
scope: "email"
options:
display: popup
services.yml
parameters:
my_user_provider.class: AppBundle\Security\Core\User\FOSUBUserProvider
services:
my_user_provider:
class: "%my_user_provider.class%"
arguments: [@fos_user.user_manager,{facebook: facebookId}]
用户提供商
<?php
namespace AppBundle\Security\Core\User;
use AppBundle\Entity\User;
use HWI\Bundle\OAuthBundle\OAuth\Response\UserResponseInterface;
use HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider as BaseUserProvider;
use FOS\UserBundle\Model\UserInterface as FOSUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* AppBundle\Security\Core\User\FOSUBUserProvider
*
* @author Ivan Molchanov <ivan.molchanov@opensoftdev.ru>
*/
class FOSUBUserProvider extends BaseUserProvider
{
/**
* @param UserInterface $user
* @param UserResponseInterface $response
* @return void
*/
public function connect(UserInterface $user, UserResponseInterface $response)
{
$property = $this->getProperty($response);
$username = $response->getUsername();
/** @var User $previousUser */
if (null !== $previousUser = $this->userManager->findUserBy([$property => $username])) {
$previousUser->setFacebookId(null);
$previousUser->setFacebookAccessToken(null);
$this->userManager->updateUser($previousUser);
}
/** @var User $user */
$user->setFacebookId($username);
$user->setFacebookAccessToken($response->getAccessToken());
$this->userManager->updateUser($user);
}
/**
* @param UserResponseInterface $response
* @return FOSUserInterface
*/
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
/** @var User $user */
$username = $response->getUsername();
$user = $this->userManager->findUserBy([$this->getProperty($response) => $username]);
if (null === $user) {
$user = $this->userManager->createUser();
$user->setFacebookId($username);
$user->setFacebookAccessToken($response->getAccessToken());
$user->setUsername($username);
$user->setEmail($username);
$user->setPassword($username);
$user->setEnabled(true);
$this->userManager->updateUser($user);
return $user;
}
$user = parent::loadUserByOAuthUserResponse($response);
$user->setFacebookAccessToken($response->getAccessToken());
return $user;
}
}
login.html.twig
{% extends "::base.html.twig" %}
{% trans_default_domain 'FOSUserBundle' %}
{% block content %}
<div class="row">
<div class="col-md-6">
{% if error %}
<div class="errors">{{ error|trans }}</div>
{% endif %}
<form class="form-horizontal" action="{{ path("fos_user_security_check") }}" method="post">
<div class="form-group">
<label for="username" class="col-sm-3 control-label">{{ 'security.login.username'|trans }}</label>
<div class="col-sm-9">
<input type="text" class="form-control" id="username" name="_username" value="{{ last_username }}"/>
</div>
</div>
<div class="form-group">
<label for="password" class="col-sm-3 control-label">{{ 'security.login.password'|trans }}</label>
<div class="col-sm-9">
<input type="password" class="form-control" id="password" name="_password"/>
<a href="{{ path("fos_user_resetting_check_email") }}">{% trans %}Reset password{% endtrans %}</a>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<div class="checkbox">
<label>
<input type="checkbox" id="remember_me" name="_remember_me" checked/>
{{ 'security.login.remember_me'|trans }}
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-3 col-sm-9">
<button type="submit" id="_submit" name="_submit" class="btn btn-success">
<i class="icon ion-log-in"></i>
{{ 'security.login.submit'|trans }}
</button>
<button class="btn btn-primary facebook-login-button">
<i class="icon ion-social-facebook"></i>
{% trans %}Log in via Facebook{% endtrans %}
</button>
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/>
</div>
</div>
</form>
</div>
<div class="col-md-6 registration">
{% trans %}If you don't have an account you could create it here:{% endtrans %}
<br/>
<a href="{{ path('fos_user_registration_register') }}" class="btn btn-primary btn-lg">
{% trans %}Registration{% endtrans %}
</a>
</div>
</div>
<div id="fb-root"></div>
{% render(controller('HWIOAuthBundle:Connect:connect')) %}
{% endblock content %}
{% block foot_script %}
{{ parent() }}
<script src="//connect.facebook.net/en_US/all.js" id="facebook-jssdk" type="application/javascript"></script>
<script>
//init facebook
window.fbAsyncInit = function ()
{
FB.init(
{
appId: '{{ facebook_id }}',
status: true,
xfbml: true,
cookie: true,
version: 'v2.3'
}
);
};
$('.facebook-login-button').on(
'click', function ()
{
FB.getLoginStatus(
function (response)
{
if (response.status === 'connected') {
document.location = "{{ url("hwi_oauth_service_redirect", {service: "facebook"}) }}";
} else {
FB.login(
function (response)
{
if (response.authResponse) {
document.location = "{{ url("hwi_oauth_service_redirect", {service: "facebook"}) }}";
} else {
alert('Cancelled.');
}
}, {scope: 'email'}
);
}
}
);
}
);
</script>
{% endblock foot_script %}