2011-11-17 35 views
5

Tôi cần có url riêng cho biểu mẫu đăng nhập đơn giản (tên người dùng/mật khẩu) đã tồn tại trên/đăng nhập và một số url như/login-via-facebook để đăng nhập thông qua quy trình OaFacebookBundle oauth.Cách tạo url riêng biệt để đăng nhập qua Facebook bằng FOSFacebookBundle trong Symfony2

Bây giờ tôi không thể hiểu cách kích hoạt thủ tục oauth-facebook bằng url, nó chỉ hoạt động nếu tôi cố gắng truy cập url được liệt kê trong "access_control".

Cảm ơn trước!


@Matt, cảm ơn bạn rất nhiều vì lời giải thích của bạn! Tôi cố gắng để làm theo câu trả lời của bạn, nhưng vẫn có một vấn đề, tôi không đề cập đến mà tôi đã sử dụng FOSUserBundle,

tôi security.yml:

providers: 
    chain_provider: 
     providers: [fos_userbundle, fos_facebook] 
    fos_userbundle: 
     id: fos_user.user_manager 
    fos_facebook: 
     id: fos_facebook.auth 

firewalls:  
    public: 
     pattern: ^/ 
     fos_facebook: 
     app_url: "" 
     server_url: "" 
     login_path: /login 
     check_path: /login_check/facebook 
     provider: fos_userbundle 
     fos_userbundle: 
     login_path: /login 
     check_path: /login_check/form 
     provider: fos_userbundle 
     anonymous: true 
     logout: true` 

như vậy, vào thời điểm này nó ném một ngoại lệ: InvalidConfigurationException: Unrecognized options "fos_userbundle" under "security.firewalls.public" và nếu tôi thay đổi fos_userbundle để form_login trong tường lửa công cộng (nhưng tôi nên làm điều này ở tất cả?), nó ném một ngoại lệ You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.

+0

Tôi đã thêm một theo dõi câu trả lời của tôi. – Matt

Trả lời

4

Bí quyết là phải có hai mục tách ra trong tường lửa của bạn, một cho biểu mẫu đăng nhập và một cho đăng nhập facebook. Nhưng trong trường hợp của tôi, tôi có một url đăng nhập duy nhất nơi người dùng có thể đăng nhập bằng thông tin đăng nhập của mình hoặc nhấp vào một kết nối Facebook để xác thực qua API OAuth2 của Facebook bằng cách sử dụng FOSFacebookBundle. Dưới đây là một mẫu của tập tin security.yml cấu hình của tôi để làm cho công việc này:

security: 
    factories: 
    - "%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml" 

    providers: 
    chain_provider: 
     providers: [acme.form_provider, acme.facebook_provider] 
    acme.form_provider: 
     id: acme.user_provider.form 
    acme.facebook_provider: 
     id: acme.user_provider.facebook 

    firewalls: 
    dev: 
     pattern: ^/(_(profiler|wdt)|css|images|js)/ 
     security: false 

    public: 
     pattern: ^/ 
     fos_facebook: 
     app_url: "your_app_url" 
     server_url: "your_server_url" 
     login_path: /login 
     check_path: /login_check/facebook 
     provider: acme.facebook_provider 
     form_login: 
     login_path: /login 
     check_path: /login_check/form 
     provider: acme.form_provider 
     anonymous: true 
     logout: true 

    role_hierarchy: 
    ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] 

Và đây là một mẫu của tập tin routing.yml tôi được sử dụng để xác định các tuyến đường an ninh cần thiết để thực hiện công việc này:

# This is defined to let the user log in. The controller for 
    # route display the login form and a facebook connect button 
_security_login: 
    pattern: /login 
    defaults: { _controller: AcmeAcmeBundle:Main:login } 

# This is defined for the form login authentication, 
# no controller is associated with it 
_security_check_form: 
    pattern: /login_check/form 

# This is defined for facebook login authentication, 
# a controller is associated with it but does nothing 
_security_check_facebook: 
    pattern: /login_check/facebook 
      defaults: { _controller: AcmeAcmeBundle:Main:loginCheckFacebook } 

_security_logout: 
    pattern: /logout 
    defaults: { _controller: AcmeAcmeBundle:Main:logout } 

Sử dụng security.yml trước đây, cơ chế bảo mật sẽ kiểm tra người dùng đã đăng nhập bằng biểu mẫu trước khi người dùng đăng nhập bằng facebook. Điều này là do thứ tự các nhà cung cấp được xác định trong số chain_provider. Trên mỗi yêu cầu, kiểm tra FOSFacebookBundle nếu có cookie facebook oauth2, nếu có, nó sẽ cố gắng tải người dùng của bạn. Nếu nó không tìm thấy cookie, quá trình xác thực sẽ thử một nhà cung cấp khác, nếu nó được xác định sau nhà cung cấp facebook.

Trong trường hợp của bạn, khi người dùng cố gắng truy cập url được bảo vệ (trong access_control), trang đăng nhập facebook được hiển thị và xác thực, sau đó được chuyển hướng đến trang web của bạn, cookie được tìm thấy và người dùng được xác thực thành công bởi FOSFacebookBundle. Để kích hoạt quá trình xác thực theo cách thủ công, hãy đặt nút kết nối facebook trên trang web của bạn, sau đó, trong javascript, chuyển hướng người dùng đến một trang khác trên trang web của bạn. Bằng cách này, cookie sẽ được đặt bằng nút kết nối và FOSFacebookBundle sẽ xác thực anh ấy theo yêu cầu tiếp theo. Những gì tôi làm, là chuyển hướng người dùng đến đường dẫn login_check cho facebook trong javascript khi nút kết nối facebook đã thành công. Bằng cách này, cơ chế bảo mật sẽ chuyển hướng anh ta đến nơi nó được ghi trong cấu hình bảo mật.

Tôi hy vọng điều này sẽ giúp bạn đạt được những gì bạn muốn. Đừng ngần ngại đặt câu hỏi thêm nếu có điều gì đó không rõ ràng.

@ Follow-up # 1

Thật vậy, bạn không thể đặt fos_userbundle dưới nút public trong cấu hình tường lửa vì nó không phải là một lựa chọn hợp lệ.Chuỗi fos_userbundle được sử dụng để tham chiếu FOSUserBundle lớp UserProvider. Tôi chưa bao giờ sử dụng gói này nhưng đọc tài liệu, bạn nên sử dụng form_login. Bạn có thể xem tài liệu của FOSUserBundle trong Step #5 trở xuống. Lỗi bạn đề cập là lẻ vì nó cho bạn biết rằng login_path không được tường lửa xử lý nhưng đó là trường hợp do tường lửa khớp với bất kỳ thứ gì bắt đầu bằng một số / (^/). Bạn không chắc chắn những gì đang xảy ra nhưng bạn đang đi đúng hướng. Sử dụng form_login và cố gắng kiểm tra lý do tại sao nó không hoạt động từ đó.

Kính trọng,
Matt

+0

cảm ơn bạn rất nhiều, tôi đã chỉnh sửa câu hỏi, hãy xem bạn có thời gian không. – synthetic

7

Bạn đã kiểm tra security.yml của bạn cho:

factories: 
    - "%kernel.root_dir%/../vendor/bundles/FOS/FacebookBundle/Resources/config/security_factories.xml" 

Điều quan trọng bởi vì nó sẽ tính phí các tùy chọn còn thiếu cho dịch vụ.

+0

Điều này thực sự đã giải quyết một trong các lỗi của tôi. Cảm ơn bạn đã nhập bài trong chủ đề này – Hezad

1

Có một ví dụ đơn giản Bundle mà thực hiện cả hai FOSUserBundle và FOSFacebookBundle nếu bạn muốn tìm https://github.com/ollietb/OhFOSFacebookUserBundle

+0

Cảm ơn bạn đã xuất bản bài đăng này! Tôi đã tạo một ứng dụng Symfony 2.1 đầy đủ bằng cách sử dụng mã của bạn: https://github.com/meonkeys/symfony21-dual-auth –

+0

Đó là git repo đã di chuyển. URL mới: https://github.com/meonkeys/symfony2-dual-auth –

Các vấn đề liên quan