[英]Binding Facebook Connect with HWIOAuthBundle in Symfony2
I've read documentations and examples from few sources but still can't get this HWIOAuthBundle works. 我已经从几个来源阅读了文档和示例,但仍然无法使HWIOAuthBundle正常工作。 I've login form using user ID and password which added manually in Admin section that already works fine.
我已经使用用户ID和密码登录了表单,该用户ID和密码已在“管理”部分手动添加,并且已经可以正常使用。
I want to add Binding Facebook Button in User Area after they login successfully, so they can login with normal ID/Password either Facebook Login in future. 他们成功登录后,我想在用户区域中添加“绑定Facebook按钮”,以便他们将来可以使用普通ID /密码登录或通过Facebook登录。 I've searching about this HWIOAuthBundle but can't find any similar case like this.
我正在搜索此HWIOAuthBundle,但找不到类似的情况。
My Security : 我的安全:
security:
encoders:
Sifo\UserBundle\Entity\Student: plaintext
providers:
user_area:
entity: { class: SifoUserBundle:Student, property: code }
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
anonymous: true
login:
pattern: ^/user/login$
security: false
user_area:
pattern: ^/user
anonymous: false
provider: user_area
form_login:
check_path: /user/login_check
login_path: /user/login
logout:
path: /user/logout
target: /user
user_area_socials:
anonymous: false
oauth:
resource_owners:
facebook: "/login/check-facebook"
login_path: /login
use_forward: false
failure_path: /login
oauth_user_provider:
service: hwi_oauth.user.provider.entity
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user/connect, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/user/, roles: ROLE_USER }
Student Entity : 学生实体:
<?php
namespace Sifo\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* Student
*/
class Student implements UserInterface, \Serializable
{
/**
* @var integer
*/
private $id;
/**
* @var string
*/
private $email;
/**
* @var string
*/
private $code;
/**
* @var string
*/
private $facebookId;
/**
* @var string
*/
private $facebookAccessToken;
app/config/routing.yml 应用程序/配置/ routing.yml中
hwi_oauth_redirect:
resource: "@HWIOAuthBundle/Resources/config/routing/redirect.xml"
prefix: /user
hwi_oauth_login:
resource: "@HWIOAuthBundle/Resources/config/routing/login.xml"
prefix: /login
facebook_login:
pattern: /login/check-facebook
app/config/config.yml 应用程序/配置/ config.yml
hwi_oauth:
# name of the firewall in which this bundle is active, this setting MUST be set
firewall_name: user_area_socials
resource_owners:
facebook:
type: facebook
client_id: XXXXX73105XXXXX
client_secret: XXXXX5534ce8d0c50893fbb9c45XXXXX
scope: "email"
services:
hwi_oauth.user.provider.entity:
class: HWI\Bundle\OAuthBundle\Security\Core\User\OAuthUserProvider
Login Form (login.html.twig) : 登录表单(login.html.twig):
<form class="form-signin" action="{{ path('user_login_check') }}" method="post">
<h2 class="form-signin-heading">sign in now</h2>
<div class="login-wrap">
<input type="text" class="form-control" placeholder="User ID" autofocus id="username" name="_username" />
<input type="password" class="form-control" placeholder="Password" id="password" name="_password" />
<label class="checkbox">
<input type="checkbox" value="remember-me"> Remember me
<span class="pull-right">
<a href="{{ path('public_default') }}"><i class="icon-home"></i> Back to home</a>
</span>
</label>
<button class="btn btn-lg btn-login btn-block" type="submit">Sign in</button>
<p>or you can sign in via social network</p>
<div class="login-social-link">
<a href="{{ path('user_facebook_login') }}" class="facebook">
<i class="icon-facebook"></i>
Facebook
</a>
<a href="{{ path('user_twitter_login') }}" class="twitter">
<i class="icon-twitter"></i>
Twitter
</a>
</div>
</div>
</form>
Routing for user_facebook_login
: 路由
user_facebook_login
:
user_facebook_login:
pattern: /login_facebook
defaults: { _controller: "SifoUserBundle:Default:facebook" }
My Controller : 我的控制器:
<?php
namespace Sifo\UserBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\SecurityContext;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Sifo\UserBundle\Form\DefaultType;
class DefaultController extends Controller
{
public function facebookAction()
{
return $this->render('SifoUserBundle:Default:facebook.html.twig');
}
public function loginAction()
{
$request = $this->getRequest();
$session = $request->getSession();
// get the login error if there is one
if ($request->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $request->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $session->get(SecurityContext::AUTHENTICATION_ERROR);
$session->remove(SecurityContext::AUTHENTICATION_ERROR);
}
return $this->render('SifoUserBundle:Default:login.html.twig', array(
// last username entered by the user
'last_username' => $session->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
}
}
facebook.html.twig : facebook.html.twig:
<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body class="login-body">
<script>
// This is called with the results from from FB.getLoginStatus().
function statusChangeCallback(response) {
console.log('statusChangeCallback');
console.log(response);
// The response object is returned with a status field that lets the
// app know the current login status of the person.
// Full docs on the response object can be found in the documentation
// for FB.getLoginStatus().
if (response.status === 'connected') {
// connected
document.location = "{{ url("hwi_oauth_service_redirect", {service: "facebook"}) }}";
} else if (response.status === 'not_authorized') {
// not_authorized
FB.login(function(response) {
if (response.authResponse) {
document.location = "{{ url("hwi_oauth_service_redirect", {service: "facebook"}) }}";
} else {
alert('Cancelled.');
}
}, {scope: 'email'});
} else {
// The person is not logged into Facebook, so we're not sure if
// they are logged into this app or not.
document.getElementById('status').innerHTML = 'Please log ' +
'into Facebook.';
}
}
// This function is called when someone finishes with the Login
// Button. See the onlogin handler attached to it in the sample
// code below.
function checkLoginState() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
window.fbAsyncInit = function() {
FB.init({
appId : 'XXXXX73105XXXXX',
cookie : true, // enable cookies to allow the server to access
// the session
xfbml : true, // parse social plugins on this page
version : 'v2.0' // use version 2.0
});
// Now that we've initialized the JavaScript SDK, we call
// FB.getLoginStatus(). This function gets the state of the
// person visiting this page and can return one of three states to
// the callback you provide. They can be:
//
// 1. Logged into your app ('connected')
// 2. Logged into Facebook, but not your app ('not_authorized')
// 3. Not logged into Facebook and can't tell if they are logged into
// your app or not.
//
// These three cases are handled in the callback function.
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
};
// Load the SDK asynchronously
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
// Here we run a very simple test of the Graph API after login is
// successful. See statusChangeCallback() for when this call is made.
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Successful login for: ' + response.name);
document.getElementById('status').innerHTML =
'Thanks for logging in, ' + response.name + '!';
});
}
</script>
</body>
</html>
You need to create your own provider, which implements OAuthAwareUserProviderInterface
. 您需要创建自己的提供程序,该提供程序实现
OAuthAwareUserProviderInterface
。 In loadUserByOAuthUserResponse
method from $response
parameter you can get any info about Facebook-user. 在
$response
参数的loadUserByOAuthUserResponse
方法中,您可以获得有关Facebook用户的任何信息。 Example: 例:
class MyOAuthProvider implements UserProviderInterface, OAuthAwareUserProviderInterface
{
public function loadUserByOAuthUserResponse(UserResponseInterface $response)
{
$token = $response->getAccessToken();
$facebookId = $response->getUsername(); // Facebook ID, e.g. 537091253102004
$username = $response->getRealName();
$email = $response->getEmail();
// search user in database
$result = $this->em->getRepository('AppUserBundle:User')->findOneBy(
array(
'facebookId' => $facebookId
)
);
if(!$result) {
$user = new User();
$user->setEmail($email);
$user->setUsername($username);
$user->setFacebookId($facebookId);
// ..
// save to database instructions
// ..
}
return $this->loadUserByUsername($username);
}
// other methods
}
Don't forget specify your custom provider in app/config/config.yml 不要忘记在app / config / config.yml中指定您的自定义提供程序
services:
app.user.provider:
class: App\UserBundle\Entity\MyOAuthProvider
and in app/config/security.yml 并在app / config / security.yml中
firewalls:
...
user_area_socials:
oauth:
oauth_user_provider:
service: app.user.provider
Read more in docs: How to Create a custom User Provider 在文档中阅读更多信息: 如何创建自定义用户提供程序
Take a look this that helped me to connect to FB, you can save whatever you want in the DB using the response from FB, for your template, I use this code for my registration form: 看一下这有助于我连接到FB,您可以使用FB的响应将所需的内容保存在DB中,对于您的模板,我将以下代码用于我的注册表格:
<script>
window.fbAsyncInit = function() {
// init the FB JS SDK
FB.init({
appId : 'XXXX', // App ID from the app dashboard
//channelUrl : '//yourdomain.com/channel.html', // Channel file for x-domain comms
status : true, // Check Facebook Login status
xfbml : true // Look for social plugins on the page
});
};
// Load the SDK asynchronously
// This javascript must be after body html tag
/*(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));*/
function fb_login() {
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
// connected
//alert('Already connected, redirect to login page to create token.');
document.location = "{{ url("hwi_oauth_service_redirect", {service: "facebook"}) }}";
} else {
// not_authorized
FB.login(function(response) {
if (response.authResponse) {
document.location = "{{ url("hwi_oauth_service_redirect", {service: "facebook"}) }}";
} else {
//alert('Cancelled.');
}
}, {display: 'popup', scope: 'email'});
}
});
}
</script>
<p>
<div class="fb-login-button" scope="email" registration-url="{{ path("hwi_oauth_service_redirect", {service: "facebook"}) }}" data-width="200">Registrarse con Facebook</div>
</p>
<form class="form_theme" action="{{ path('fos_user_registration_register') }}" {{ form_enctype(form) }} method="POST">
{{ form_widget(form) }}
<div class="submit center">
<input type="submit" value="{{ 'registration.submit'|trans({}, 'FOSUserBundle') }}" />
</div>
</form>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.