Angular app integrated with key cloak is redirecting to login page ONLY ON page refresh - keycloak

I have an Angular app, which is configured with key cloak Authentication. Once every 30minutes, the cookie/session set by key cloak gets expired . As per the default behavior, the app is redirecting to login page when the user refreshes the app manually.
But I wanted it some thing like whenever the token get expired , redirect the current session to key cloak login page. (this should happen automatically, i.e., even with out user manual refreshes the page.)
There is a keycloak API, that collects the user login-logout entries in it.
"http://localhost:8080/auth/admin/realms//events?dateFrom=2022-02-09&dateTo=2022-02-10&first=0&max=9999999&type=LOGIN&type=LOGIN_ERROR&type=LOGOUT&type=LOGOUT_ERROR"
when ever user is refreshing the Angular App on browser window, each of refresh action is considered as a login entries and this API response keep on increasing with log. How to prevent this and get the log only for Login & Logout entires.
Here is the configuration set in app.init.ts
import { KeycloakService } from 'keycloak-angular';
import {keycloakConfigs } from '../../assets/config/serverdetails.json';
export function initializeKeycloak(keycloak: KeycloakService): () => Promise<boolean> {
return () =>
keycloak.init({
config: {
url: keycloakConfigs.Url,
realm: keycloakConfigs.Realm,
clientId: keycloakConfigs.ClientId,
},
initOptions: {
onLoad: 'login-required',
checkLoginIframe: true,
checkLoginIframeInterval: 25
},
loadUserProfileAtStartUp: true
});
}

Related

keycloak init method gives authenticated false even when i login a with valid user

Hello I am using keycloak with react , i used some keycloak code that i got from internet for keycloak and react integration . the problem is that when i use that code initially when i login in and get redirect from the keycloak login theme the authenticated is true which is okay . but as i refresh the page it is no longer true and become false.
here is the code:
keycloak
.init({ checkLoginIframe: false })
.then((authenticated) => {
console.log("authentication status",authenticated)
}).catch((err)=>{
console.log("error",err)
})
I want to make a http request on basis of token but for that i want to check if authentiacted is true or not.
the authenticated is true only first time when i am redirected from keycloak login page but as i refresh page its always false.i am using react for client side.

Auth0 error after failed login attempt

I am using Auth0 to authenticate users by redirecting them to facebook.
But the problem I am facing is that if a user types in incorrect account credentials the first time and succeeds on the second attempt the redirect does not happen, instead it takes me to "Oops!, something went wrong" page with the following message:
"invalid_request: You probably pressed the back button or there is some issue with cookies, since we couldn't find your session. Try logging in again from the application and if the problem persist contact the administrator."
EDIT: I am using the below Auth0Lock code on the client side.
var lock = new Auth0Lock('<%= auth0.clientId %>', '<%= auth0.domain %>', {
//redirect mode
auth: {
redirectUrl: '<%= auth0.callback %>',
responseType: 'code',
params: {
scope: 'openid' // Learn about scopes: https://auth0.com/docs/scopes
}
},
autoclose: true,
theme: {
logo: 'https://xxxxxx/logo_orange.jpg'
},
languageDictionary: {
title: "test"
}
});
lock.on("unrecoverable_error",function(err) {
console.log(err);
});
lock.on("authorization_error",function(err) {
console.log(err);
});
Once I select Login with facebook I am redirected to facebook url that looks something like link
There if I enter the email/password incorrectly the first time the page refreshes and on the second try if I succeed,instead of taking me back to my app the auth0 generic error page => doc shows up with the error I mentioned at the top.On the server side passport seems to correctly authenticate the user.
PS: Chrome is taking me to a login page which has a login form on top and center but firefox just has login at the center of the page.For chrome if I use the top login form and has a failed login attempt on second successful attempt I am taken to my facebook page i.e no redirect happens.
There's at least one issue and that one is a Facebook problem. Their login page is showing two login forms:
The TOP form has an action equal to:
https://www.facebook.com/login.php?login_attempt=1&lwv=100
while the CENTER one has:
/login.php?login_attempt=1&next=https://www.facebook.com/v2.4/dialog/oauth?redirect_uri=https%3A%2F%2Flogin.eu.auth0.com%2Flogin%2Fcallback&state=[state]&response_type=code&client_id=[client_id]&ret=login&logger_id=1bf0be0d-4b64-43a6-b112-79a30100fa5b&lwv=100
This means that submitting the top form does not maintain enough information to be able to return back to your application. Now, there's still the issue of the Auth0 generic page being shown, but that one I'm unable to reproduce. If you think it's worthwhile, then do upload an HAR for review, even one where you strip all cookies might help.
Update:
Looked at the HAR, the second issue seems to be caused by an authentication request to Facebook that does not pass through Auth0. There's a request to your application, but that one does not complete an then there's this second request that will trigger the Auth0 error page.
Expected flow:
https://test.auth0.com/authorize
https://www.facebook.com/dialog/oauth
https://www.facebook.com/login.php (user authenticates here)
https://www.facebook.com/v2.8/dialog/oauth
https://test.auth0.com/login/callback
https://localhost:8080/callback
What's causing the error generic page, before your localhost request completes another request is issued:
https://www.facebook.com/v2.8/dialog/oauth
https://test.auth0.com/login/callback (generic error page shown here)
The error is caused because https://test.auth0.com/login/callback is called without first going through https://test.auth0.com/authorize to setup the authentication transaction state.
Given the request to your application localhost is marked as incomplete I would start looking in your code to see if there's any reason for that request to not complete.

Ember Torii facebook authentication not able to get user email

I am using Ember CLI + ember simple auth torii link
to get authentication code from facebook for my ember app.
This is my environment.js file
ENV['torii'] = {
providers: {
'facebook-oauth2': {
apiKey: '865549306850377',
scope: 'email',
//redirectUri: window.document.location.href
redirectUri: 'http://localhost:4200/'
}
}
};
And my login controller looks like this -
facebook: function() {
var _this = this;
this.get('session').authenticate('simple-auth-authenticator:torii', 'facebook-oauth2').then(function(data){
console.log("status - ", _this.get('session'));
});
}
And login.hbs -
<li><button {{action "facebook" "facebook-oauth2"}}>Facebook OAuth2</button></li>
After the user clicks on the link, a facebook popup opens and ember app gets a token.
How do I get the user's email id along with this token ?
Has anybody faced a similar issue ?
So you're using oauth2, so all you're ever going to get is an authorization token. With this token, you can then go off and request other information. The token is basically just there to speed up the validation of users against your application.
If you want to get user information, you would need to create another method (probably on your server-side), which swaps the authorization code for an access token: like so (or alternatively you can request an access token directly, which would remove the need for a server-side solution.
Using the access Token you can then request the Facebook User ID, using the debug token endpoint, and after that you will be able get to any endpoint to get the information you need.

FacebookJavaScriptLoginHelper fails to authenticate user on first page refresh

I'm creating a Facebook app for mobile devices. Such application is displayed within a mobile browser, unlike Facebook canvas pages which are held in an iframe.
I'm using a mix of JS and PHP SDK to authorize and authenticate a user. The user needs to be already logged into Facebook to use my app. If not, they need to log in with Facebook login button. As a bridge between JS and PHP SDKs I'm using FacebookJavaScriptLoginHelper.
Part of my Facebook.php library doing the job:
<?php
// Initialize the SDK
FacebookSession::setDefaultApplication($this->app_id, $this->app_secret);
// Create the login helper
$this->helper = new FacebookJavaScriptLoginHelper();
try {
$this->session = $this->helper->getSession();
} catch(FacebookRequestException $ex) {
// When Facebook returns an error
} catch(Exception $ex) {
// When validation fails or other local issues
}
if ($this->session) {
// User logged in
$this->session = new FacebookSession($this->session->getToken());
}
?>
Facebook JS init:
<script type="text/javascript">
window.fbAsyncInit = function() {
FB.init({
appId: '{my app id}',
status: true,
xfbml: true,
cookie: true
});
}
FB.getLoginStatus(function(response) {
console.dir(response);
});
</script>
The above code works fine but there's a specific case when it fails. Let's assume I have two tabs open in my browser: in the first tab I have my app open, in the second one - I'm logged into Facebook. Two scenarios can take place:
I log out of Facebook and refresh the tab with my app. The result is correct:
FacebookSession is NULL
response.status from FB.getLoginStatus is 'unknown'. The user is not
logged in.
I go to the second tab, log back into Facebook and refresh the first tab with my app. The result is incorrect, but only on the first refresh:
FacebookSession is still NULL, even if
response.status of FB.getLoginStatus is 'connected'
The reason behind this fail on first refresh seems to be obvious: In the moment of reloading the page PHP SDK is triggered before Facebook cookie is refreshed. However, it's never a problem when the user logs out - in this case, somehow FacebookSession is updated instantly, as expected.
How come it does not work the same when the user logs into Facebook?
Does this help?
Subsequent calls to FB.getLoginStatus will return data from this cached response. This can cause problems where the user has logged into (or out of) Facebook since the last full session lookup, or if the user has removed your application in their account settings.
To get around this, you call FB.getLoginStatus with the second parameter set to true to force a roundtrip to Facebook - effectively refreshing the cache of the response object.
FB.getLoginStatus(function(response) {
// this will be called when the roundtrip to Facebook has completed
}, true);
Source: https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus
Section: Roundtrips to Facebook's servers

Redirect after user has logged in

I'm pretty new to Angular, and right now I'm just trying to get all my routes set up and working as I'd like.
Setup:
When a user navigates to certain pages (/settings for this example) the app should check if there is a user already logged in. If there is continue as usual. Otherwise the user should go to the login page (/login).
What I'd like:
After the user has successfully logged in they should go to the page they were originally trying to get to (/settings)
My question:
Is there an "Angular way" to remember where the user was trying to go to?
Relevant code:
app.js
.when('/settings', {
templateUrl: '/views/auth/settings.html',
controller: 'SettingsCtrl',
resolve: {
currentUser: function($q, $location, Auth) {
var deferred = $q.defer();
var noUser = function() {
//remember where the user was trying to go
$location.path("/login")
};
Auth.checkLogin(function() {
if (Auth.currentUser()) {
deferred.resolve(Auth.currentUser());
} else {
deferred.reject(noUser());
}
});
return deferred.promise;
}
}
})
login.js
$scope.submit = function() {
if(!$scope.logInForm.$invalid) {
Auth.login($scope.login, $scope.password, $scope.remember_me)
//go to the page the user was trying to get to
}
};
Much thanks to John Lindquist for the video which got me this far.
First off, you do not want to redirect the user to a login page.
An ideal flow in a single page web app is as follows:
A user visits a web site. The web site replies with the static assets for the
angular app at the specific route (e.g. /profile/edit).
The controller (for the given route) makes a call to an API using $http, $route, or other mechanism (e.g. to pre-fill the Edit Profile form with details from the logged in user's account via a GET to /api/v1/users/profile)
If/while the client receives a 401 from the API, show a modal to
login, and replay the API call.
The API call succeeds (in this case, the user can view a pre-filled Edit Profile form for their account.)
How can you do #3? The answer is $http Response Interceptors.
For purposes of global error handling, authentication or any kind of
synchronous or asynchronous preprocessing of received responses, it is
desirable to be able to intercept responses for http requests before
they are handed over to the application code that initiated these
requests. The response interceptors leverage the promise apis to
fulfil this need for both synchronous and asynchronous preprocessing.
http://docs.angularjs.org/api/ng.$http
Now that we know what the ideal user experience should be, how do we do it?
There is an example here: http://witoldsz.github.com/angular-http-auth/
The example is based on this article:
http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application
Good luck and happy Angularing!