Symfony 2.1 FOSFacebookBundle infinite loop after login - loops

I've a little problem with the FOSFacebookBundle integration to my website. When I click on the "Connexion" button, user is redirected to /facebook/login_check, and some random token are added to the url (state and code). But a new value is given to these tokens every second, and the page is still blank.
Here is my code:
[config.yml]
security:
providers:
fos_userbundle:
id: fos_user.user_manager
my_fos_facebook_provider:
id: my.facebook.user
firewalls:
public:
pattern: ^/facebook
fos_facebook:
app_url: "http://www.facebook.com/apps/application.php?id=[MY_APP_ID]"
server_url: "http://localhost/[MY_APP]/app_dev/"
login_path: /facebook/login
check_path: /facebook/login_check
provider: my_fos_facebook_provider
default_target_path: /
anonymous: true
logout:
handlers: ["fos_facebook.logout_handler"]
main:
form_login:
login_path: /login
check_path: /login_check
provider: fos_userbundle
[routing.yml]
_security_check:
pattern: /facebook/login_check
_security_logout:
pattern: /logout
[layout.html.twig]
<script>
function goLogIn(){
window.location.href = "{{ path('_security_check') }}";
}
function onFbInit() {
if (typeof(FB) != 'undefined' && FB != null ) {
FB.Event.subscribe('auth.statusChange', function(response) {
if (response.session || response.authResponse) {
setTimeout(goLogIn, 500);
} else {
window.location.href = "{{ path('fos_user_security_logout') }}";
}
});
}
}
</script>
Do you know why ?
Thanks in advance.
PS: I use Symfony 2.1 and FOSUserBundle.

Related

HWIOAuth Symfony 4: A service definition must be an array or a string starting with "#" but string found for servic

I'm trying to integrate the FOS with HWIO on Symfony 4. Unfortunately, I ran into an error as seen below:
In FileLoader.php line 168:
A service definition must be an array or a string starting with "#" but string found for service "class" in D:\web-projects\pcrmanagement\config/services.yaml. Check your YAML syntax in D:\web-projects\pcrmanagement\config/services.yaml (which is loaded in resource "D:\web-projects\pcrmanagement\config/services.yaml").
In YamlFileLoader.php line 336:
A service definition must be an array or a string starting with "#" but string found for service "class" in D:\web-projects\pcrmanagement\config/services.yaml. Check your YAML syntax.
Here are my code below, I'll go and post only what you need to see, if you need more code to review, I can put more.
#config/hwi_oauth.yaml
hwi_oauth:
firewall_names: [main]
fosub:
username_iterations: 30
properties:
googleplus: username
resource_owners:
google:
type: google
client_id: secret
client_secret: secret
scope: "email profile"
options:
csrf: true
# security.yaml
providers:
in_memory: { memory: ~ }
fos_userbundle:
id: fos_user.user_provider.username
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager
oauth:
resource_owners:
facebook: "/login/check-facebook"
google: "/login/check-google"
my_custom_provider: "/login/check-custom"
my_github: "/login/check-github"
login_path: /login
use_forward: false
failure_path: /login
oauth_user_provider:
service: my.oauth_aware.user_provider.service
logout: true
anonymous: true
#services.yaml
my.oauth_aware.user_provider.service:
class: HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider
arguments: ['#fos_user.user_manager',{google: username}]
I think there is a problem on how he reads the arguments in services.yaml
Create your custom user_provider and extend HWI\Bundle\OAuthBundle\Security\Core\User\FOSUBUserProvider.
Then config your custom provider:
services:
App\Security\Core\User\MyFOSUBUserProvider:
arguments: ['#fos_user.user_manager', { facebook: facebook_id }]
Then change:
oauth_user_provider:
service: MyBundle\Security\Core\User\MyFOSUBUserProvider

cookie NOT setting in browser with hapi-auth-cookie plugin

I've used hapi js for my backend and react for my frontend. The front end server is running on localhost port 3000, and the backend on 8000. So i have 2 routes like this -
let userDetails = {
method: "GET",
path: "/api/user/userdata",
config: {
description: 'Get userdata',
notes: 'Returns a todo item by the id passed in the path',
tags: ['api', 'User Data'],
cors: corsHeaders,
auth: {
strategy: 'restricted',
}
},
handler: (request, h) => {
return h.response(userData)
}
}
and
let createUser = {
method: "POST",
path: "/api/user/userdata",
config: {
tags: ['api', 'User Data'],
description: 'Upload User data to the db',
cors: corsHeaders,
},
handler: async (request, h) => {
const { username, emailId, password } = request.payload
request.cookieAuth.set({ username })
return h.response('cookie created!')
}
}
now the 'post' route sets the cookie by request.cookieAuth.set({ username }),
so when i posted through postman application, it's setting the cookie in postman and the get route sends the data without any problem. But in browser, the cookie is'nt being set.
i'm using hapi-auth-cookie plugin and the registration is done like this -
await server.register(HapiAuthCookie)
server.auth.strategy('restricted', 'cookie',{
password: 'AudhASp342SID3acdh83CDASHciAS93rashdiva34a',
cookie: 'session',
isSecure: false,
ttl: 7 * 24 * 60 * 60 * 1000,
})
someone please help

Symfony API Rest login and register

I'm finishing developing a API rest with common endpoints using FOSUserBundle, FOSResBundle and FOSoAuthBundle.
In a parallel way, I'm developing another symfony app to consume the services but I'm having several doubts about how to register and login users via API endpoints. My idea is to have 2 controllers refered it's routes (such as /login and /register) and do this actions via api endpoint.
with FOSUserbundle this actions are simple but don't know how to 'consume' trough APIRest service.
I know it's only half an answer but I currently do this with login, but not registration (I don't need it).
I am using Symfony 4 and flex, but it should work on 3.4 I think. I am also using json.
Bundles
Bundles I use for this (on top of fosuser etc):
jms/serializer-bundle
lexik/jwt-authentication-bundle
friendsofsymfony/rest-bundle
Config
Fos Rest
fos_rest:
body_listener: true
param_fetcher_listener: force
format_listener:
enabled: true
rules:
- { path: ^/, priorities: [ json ], fallback_format: json, prefer_extension: true }
view:
view_response_listener: 'force'
formats:
json: true
xml: false
rss: false
mime_types:
json: ['application/json', 'application/x-json']
routing_loader:
default_format: json
include_format: false
exception:
enabled: true
Fos User
fos_user:
db_driver: orm
firewall_name: api
user_class: App\Entity\User
from_email:
address: admin#example.com
sender_name: Admin
JMS Serializer
jms_serializer:
visitors:
xml:
format_output: '%kernel.debug%'
Lexik JWT
You need you generate tokens and put their location in your .env file. More info and a guide here.
lexik_jwt_authentication:
private_key_path: '%kernel.project_dir%/%env(JWT_PRIVATE_KEY_PATH)%'
public_key_path: '%kernel.project_dir%/%env(JWT_PUBLIC_KEY_PATH)%'
pass_phrase: '%env(JWT_PASSPHRASE)%'
token_ttl: 3600 #whatever you like
token_extractors:
authorization_header: ~
cookie: ~
query_parameter: ~
Security
security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
encoders:
FOS\UserBundle\Model\UserInterface: sha512 #probably use bcrypt
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
api_login:
pattern: ^/login
stateless: true
anonymous: true
form_login:
check_path: /login
require_previous_session: false
username_parameter: username
password_parameter: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
api:
pattern: ^/
stateless: true
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/, role: IS_AUTHENTICATED_FULLY }
Routes
login:
type: rest
resource: App\Controller\LoginController
Controller
I made a loginController that is really just a placeholder to override the route
<?php
namespace App\Controller;
use FOS\RestBundle\Controller\Annotations;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Routing\ClassResourceInterface;
use FOS\RestBundle\Controller\Annotations\RouteResource;
/**
* #RouteResource("login", pluralize=false)
*/
class LoginController extends FOSRestController implements ClassResourceInterface
{
public function postAction()
{
throw new \DomainException('You should never see this');
}
}
Testing it
You can fire a POST request to /login and it should return a token!
{
"username": "my_user",
"password": "passw0rd"
}
Registration
I haven't actually done this but I have a simple enough idea...
Open a route to registration in your security.yaml
security:
firewalls:
api_register:
pattern: ^/register
anonymous: true
access_control:
- { path: ^/register$, role: IS_AUTHENTICATED_ANONYMOUSLY }
Register the route
registration:
type: rest
resource: App\Controller\RegistrationController
Write the controller method
Get the request data
User the FosUserManager to create a new user
- https://symfony.com/doc/current/bundles/FOSUserBundle/user_manager.html

callback missmatch error in angular with auth0

Hi I'm using Auth0 with Nodejs and angularjs
here is what i want to achieve
1. I want to user to signup using auth0's lock
2. as soon as user logs in a callback should be called at my nodejs server
3. after that i will get the user information and user's JWT
4. then i will redirect user to dashboard page and store the JWT in browser
What's the problem with Auth0's example
1. they provide example either for angular or nodejs standalone not the combined
2. there is combined(client server) example but that's using jade with nodejs
my code snipped
Angular snipped
var options = { auth: {
redirectUrl: 'http://localhost:3000/callback'
, responseType: 'code'
, params: {
scope: 'openid name email picture'
}
}
}
lockProvider.init({
clientID: 'cUlBNhhaIblahBlahRp6Km',
domain: 'rishabh.auth0.com',
option:options
});
node snipped
router.get('/callback',
passport.authenticate('auth0', { failureRedirect: '/url-if-something-fails' }),
function(req, res) {
console.log(req.user);
res.json({id_token:req.user});
});
Note: I've added this callbacks in auth0
http://localhost:3000/callback
but dont know why I'm facing this error for callback error when I've mentioned my redirect URL in angular side
can anyone tell me what is the problem with my code why auth0 not redirecting me to this url http://localhost:3000/callback
and the interesting thing is when i use simple lock.js instead of angular like this
<script>
var options = { auth: {
redirectUrl: 'http://localhost:3000/callback'
, responseType: 'code'
, params: {
scope: 'openid name email picture'
}
}
}
var lock = new Auth0Lock('clientID', 'rishabh.auth0.com',options);
lock.show();
</script>
then in this case my nodejs /callback route is called properly, so what I'm doing wrong with angular ?
please help
Update
this is my project structure
full code
https://github.com/LabN36/error
Config.js
var Auth0Strategy = require('passport-auth0');
var passport = require('passport');
var strategy = new Auth0Strategy({
domain: process.env.AUTH0_DOMAIN || 'rishabh.auth0.com',
clientID: process.env.AUTH0_CLIENT_ID || 'cUheWwRxm7OLdHBRzlBNvfvfvfvfvhhaI1lxRp6Km',
clientSecret: process.env.AUTH0_CLIENT_SECRET || 'e37eIZpjgBnDMBtrYMwvffvfvfvfaU4jSqt8qylZMT9Oj1EiffLGViinWQ5AiuWi1-WBwA8v3',
callbackURL: process.env.AUTH0_CALLBACK_URL || 'http://localhost:3000/callback'
}, function(accessToken, refreshToken, extraParams, profile, done) {
// accessToken is the token to call Auth0 API (not needed in the most cases)
// extraParams.id_token has the JSON Web Token
// profile has all the information from the user
console.log(extraParams.id_token);
//save user detail with token here and return token only profile
return done(null, extraParams.id_token);
});
passport.use(strategy);
// you can use this section to keep a smaller payload
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
module.exports = passport;
AngularApp.js
angular.module('workApp',['auth0.lock'])
.config(function($locationProvider,lockProvider){
var options = { auth: {
// redirect:true,
responseType: 'code',
redirectUrl: 'http://localhost:3000/callback',
params: {
scope: 'openid name email picture'
}
}
}
lockProvider.init({clientID: 'cUheWwRxm7OLdHBRzlBNhhaI1lxRp6Km',domain: 'rishabh.auth0.com',
option:options
});
$locationProvider.html5Mode(true);
})
.controller('homeCtrl',function($scope,$http,$location,$window,lock){
$scope.login = function() {
// window.alert("magic")
console.log("Messed Up really")
var vm = this;
vm.lock = lock;
lock.show();
}
}).run(function(lock){
lock.interceptHash();
lock.on('authenticated', function(authResult) {
localStorage.setItem('id_token', authResult.idToken);
lock.getProfile(authResult.idToken, function(error, profile) {
if (error) {
console.log(error);
}
localStorage.setItem('profile', JSON.stringify(profile));
});
});
})
According to the screenshot the error happens because the authentication request is made with a redirect_uri of:
http://localhost:3000/
and the allowed callback URL's are:
http://localhost:3000/callback
http://35.162.118.253:3000/callback
Also based on the code you shared you're indeed setting the redirectUrl to be http://localhost:3000/callback so there may be something on the rest of the code that either causes that value to be overridden or not used at all.
If the redirectUrl is not set, Lock will use the current page so the likely culprit is that the options you set are not being used. If you still don't find the cause for this, update the question with the code associated with how Lock is shown.
Damn, the actual root cause was already shown in the code you initially provided, but only looking now at the full code made it possible for me to catch it...
You're calling lockProvider.init() with:
{ clientID: [?], domain: [?], option: options }
when it should be called with:
{ clientID: [?], domain: [?], options: options } // options instead of option

ExtJS4 & Symfony 2

I have to mix up Symfony2 and ExtJS4. All views need to be render with ExtJS, no twig.
All the application is in a secured area, only members will be able to access it.
When an user launch the application, main viewport is displayed with login form. After connecting, the entire app is displayed.
In facts, the / route need to display viewport. It will call an ajax request to check if user is connected.
if yes, launch the app
if not, show the login form
And I don't know how to do that, the / action in my controller wait for response and I only want to launch javascript.
EDIT : the login form must be made with ExtJS.
security.yml
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login:
pattern: ^/login$
security: false
secured_area:
pattern: ^/
form_login:
check_path: /login_check
login_path: /login
logout:
path: /logout
target: /
and the loginAction
public function loginAction()
{
if ($this->get('request')->attributes->has(SecurityContext::AUTHENTICATION_ERROR)) {
$error = $this->get('request')->attributes->get(SecurityContext::AUTHENTICATION_ERROR);
} else {
$error = $this->get('request')->getSession()->get(SecurityContext::AUTHENTICATION_ERROR);
}
$json = json_encode(array(
'username' => $this->get('request')->getSession()->get(SecurityContext::LAST_USERNAME),
'error' => $error,
));
$response = new Response($json);
$response->headers->set('Content-Type', 'application/json');
return $response;
}
Process should be -
Make an ajax call to login_check
Read the json response into an object and check whatever variable is set to denote success or failure
If the user isn't logged in, show the login window
In the click event of the login button, make another ajax call to log them in
If they authenticate, return a variable to notify via json, and show the app, if not give them a hint as to what went wrong in a message.
-
var login = Ext.create('Ext.window.Window', {
id: 'login',
height: 200,
width: 350,
layout: 'anchor',
modal: true,
title: 'Welcome, Please Login',
items: [
this.username = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Username'
}),
this.password = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Password'
}),
this.submit = Ext.create('Ext.button.Button', {
text: 'Login'
})
]
});
login.submit.on('click', function (btn, e, eOpts) {
Ext.Ajax.request({
scope: this,
params: {
username: login.username.getValue(),
password: login.password.getValue()
},
url: 'yoursite/login',
success: function(response, opts) {
var obj = Ext.decode(response.responseText);
if (obj.logged_in === true) {
//Show App
} else {
//Display error message
}
}
});
});
Ext.Ajax.request({
scope: this,
url: 'yoursite/login_check',
success: function(response, opts) {
var obj = Ext.decode(response.responseText);
if (obj.username === null) {
//Show Login window
login.show();
} else {
//Logic to show app if logged in
}
}
});

Resources