2014-05-09 33 views
2

我已经阅读了几个来源的文档和例子,但仍然不能得到这个HWIOAuthBundle的作品。我已经使用用户名和密码登录表单,这些用户名和密码在管理员部分手动添加,并且已经正常工作绑定Facebook连接在Symfony2中的HWIOAuthBundle

我想在登录成功后在用户区添加绑定Facebook按钮,这样他们就可以使用正常的用户名/密码登录Facebook登录。我搜索这个HWIOAuthBundle,但无法找到任何类似的情况。

我的安全性:

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 } 

学生实体:

<?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; 

应用程序/配置/ 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 

应用程序/配置/ 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.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> 

路由为user_facebook_login

user_facebook_login: 
    pattern: /login_facebook 
    defaults: { _controller: "SifoUserBundle:Default:facebook" } 

我的控制器:

<?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:

<!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> 
  1. 如何获取Facebook ID和访问令牌并保存到数据库中。 (用于绑定Facebook)
  2. 如何检入数据库中的Facebook ID。如果存在,在我的Controller中给ROLE_USER像正常的loginAction。如果不存在抛出异常。
  3. 如果这个Bundle不能容纳我的问题,有没有更适合我需求的Bundle或函数?

只需留言或留言,如果您需要其他信息。感谢您的帮助。

回答

4

您需要创建自己的提供者,它实现了OAuthAwareUserProviderInterface。在loadUserByOAuthUserResponse方法从$response参数你可以得到任何关于Facebook用户的信息。例如:

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 
} 

不要忘记应用程序指定自定义提供/配置/ config.yml

services: 
    app.user.provider: 
     class: App\UserBundle\Entity\MyOAuthProvider 

应用程序/配置/安全性。阳明海运

firewalls: 
     ... 
     user_area_socials: 
      oauth: 
       oauth_user_provider: 
        service: app.user.provider 

详情请阅读文档:How to Create a custom User Provider

+0

Facebook最近更改了API,因此您需要将此设置为config.yml以获取电子邮件或名称:'infos_url:'https://graph.facebook.com/me?fields = id,first_name,last_name,email'' under' hwi_oauth - > resource_owners-> facebook' – Volvox

0

看看this,帮助我连接到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> 
+0

我加入Facebook的连接已经在V2.0正常登录表单,并似乎工作。看看我的问题,我编辑它。但我仍然不能保存Facebook ID第一次绑定,并检查数据库中的Facebook ID登录操作。 –