Keycloak invalid redirect_uri error with Angular - angularjs

I am using Keycloak authentication to authenticate an angular app and so far I have managed to redirect my login to keycloak server. But when redirected instead of the login page I am getting a 500 error page with the message Invalid parameter: redirect_uri.
I followed this stackoverflow answer and made sure that my client settings are correct. But no matter what I changed it to I get the same log message on keycloak console.
Keycloak log
09:39:21,369 WARN [org.keycloak.events] (default task-62) type=LOGIN_ERROR, realmId=camunda-demo-auth, clientId=camunda-demo-client, userId=null, ipAddress=127.0.0.1, error=invalid_redirect_uri, redirect_uri=http://localhost:9002/
My Client Settings
Update [Changed settings according to RobbyCornelissen's suggestions]
Angular Login Redirection
angular.element(document).ready(function () {
window._keycloak = Keycloak('../src/app/resources/keycloak.json');
window._keycloak.init({onLoad: 'login-required'})
.success(function () {
angular.bootstrap(document, ['adfWidgetSample']); // manually bootstrap Angular
});
});

Related

Intermittent problem using loginPopup MSAL JS in a REACT

I'm using MSAL JS in order to authenticate users in react application developed using REACT. Sometimes login works perfectly, redirecting users to the home page of the app. Other times login popup opens, users insert their login but then login procedure fails with this error:
hash_empty_error: Hash value cannot be processed because it is empty.
Please verify that your redirectUri is not clearing the hash.
I know this issue was raised before but never seen proper solution how to overcome this error
What worked for me was to set the redirectUri to a blank page or a page that does not implement MSAL. If your application is only using popup and silent APIs you can set this on the PublicClientApplication config like below:
export const msalConfig = {
auth: {
clientId: process.env.REACT_APP_CLIENTID,
authority: `https://login.microsoftonline.com/${process.env.REACT_APP_TENANTID}`,
redirectUri: 'http://localhost:3000/blank.html'
},
cache: {
cacheLocation: "localStorage"
}
}
If your application also needs to support redirect APIs you can set the redirectUri on a per request basis:
msalInstance.loginPopup({
redirectUri: "http://localhost:3000/blank.html"
})

How to redirect to a new link from a POST endpoint in express?

I am using react in frontend and express for the backend.
I have a problem with redirecting from a POST endpoint in express app to a link in my react app.
More Explanation: I am integrating with a payment service and after the transaction happened on the third-party website, the service will send me a POST request with the transaction status and it will redirect the user to that endpoint too.
So I am planning to receive the transaction status in express and redirect the user back to my react app in frontend.
Note : redirect() function didn't work for me
// The route for recieving payment response
app.get("/payment/response", (req, res) => {
try {
// receiving the transaction body in here and
// redirecting the user to my react website
// The below codes are not working
// return res.status(200).json({
// success: true,
// redirectUrl: "http://localhost:2200/user",
// });
// res.status(301).redirect("https://www.google.com");
// return res.status(200).json({
// success: true,
// redirectUrl: "",
// });
} catch (error) {
res.status(500).json("Something went wrong");
}
});
Problem Solved!!!
Apparently, CORS was the issue.
The react and express app is running on different ports and after allowing CORS redirect problem is solved.
In development, the CORS error was not showing up and that made the process complicated but once the app was deployed, the redirect started working.

Node API - How to link Facebook login to Angular front end?

Rewriting this question to be clearer.
I've used passport-facebook to handle login with facebook on my site.
My front end is in Angular so I know now need to understand whats the correct way of calling that api route. I already have several calls using Angular's $http service - however as this login with facebook actually re-routes the facebook page can i still use the usual:
self.loginFacebook = function )() {
var deferred = $q.defer();
var theReq = {
method: 'GET',
url: API + '/login/facebook'
};
$http(theReq)
.then(function(data){
deferred.resolve(data);
})
return deferred.promise;
}
or is it perfectly ok/secure/correct procedure to directly hit that URL in a window location:
self.loginFacebook = function (){
$window.location.href = API + '/login/facebook';
}
Furthermore, from this how do I then send a token back from the API? I can't seem to modify the callback function to do that?
router.get('/login/facebook/callback',
passport.authenticate('facebook', {
successRedirect : 'http://localhost:3000/#/',
failureRedirect : 'http://localhost:3000/#/login'
})
);
Thanks.
I was stacked on the same problem.
First part:
I allow in backend using cors and in frontend i use $httpProvider, like this:
angular.module('core', [
'ui.router',
'user'
]).config(config);
function config($httpProvider) {
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common["X-Requested-With"] = 'XMLHttpRequest';
};
The second part:
<span class="fa fa-facebook"></span> Login with facebook
This call my auth/facebook route that use passport to redirect to facebook page allowing a user to be authenticated.
If the user grant access, the callback /api/auth/facebook/callback is called and the facebook.strategy save the user with the profile data.
After saving the user, i create a special token with facebook token, id and email. This info is used to validate every time the user access to private states in the front.
My routes are something like this:
router.get('/facebook', passport.authenticate('facebook',
{ session: false, scope : 'email' }));
// handle the callback after facebook has authenticated the user
router.get('/facebook/callback',
passport.authenticate('facebook',
{session: false, failureRedirect: '/error' }),
function(req, res, next) {
var token = jwt.encode(req.user.facebook, config.secret);
res.redirect("/fb/"+token);
});
In frontend i catch the /fb/:token using a state and assign the token to my local storage, then every time the user go to a private section, the token is sent to backend and validate, if the validation pass, then the validate function return the token with the decoded data.
The only bad thing is that i don't know how to redirect to the previous state that was when the user click on login with facebook.
Also, i don't know how you are using the callback, but you need to have domain name to allow the redirect from facebook. I have created a server droplet in digitalocean to test this facebook strategy.
In the strategy you have to put the real domain in the callback function, like this:
callbackURL: "http://yourdomain.com/api/auth/facebook/callback"
In the same object where you put the secretId and clientSecret. Then, in your application in facebook developers you have to allow this domain.
Sorry for my english, i hope this info help you.
Depending on your front-end, you will need some logic that actually makes that call to your node/express API. Your HTML element could look like
<a class='btn' href='login/facebook'>Login</a>
Clicking on this element will make a call to your Express router using the endpoint of /login/facebook. Simple at that.

Sending authenticated requests to GitHub API from authorized Auth0 app user

I am having a very difficult time getting authenticated API requests to GitHub to work. I have created an authorized application in GitHub and connected it to my Auth0 account. I have no problems getting a user signed in using their GitHub account but once they are signed in I cannot make authenticated requests to the GitHub API (I am trying to set a GitHub webhook in one of the user's GitHub repos). All my requests are rejected for having incorrect credentials.
I have the JWT issued by Auth0 being sent along in each request to the GitHub API endpoint but it appears as though this is not sufficient. The Auth0 profile that comes back from my user seems to have an access_token in it, but sending this along does not work either.
Here is what my Auth0 login code looks like (using the Angular API):
angular.module('myApp').controller('LoginCtrl', ['$scope', '$http', 'auth', 'store', '$location',
function ($scope, $http, auth, store, $location) {
$scope.login = function () {
auth.signin({
authParams: {
responseType: 'token' // I think this is the default but just in case
}
}, function (profile, token) {
// Success callback
store.set('profile', profile);
store.set('token', token);
$location.path('/');
}, function () {
// Error callback
console.debug("error logging in");
});
};
}]);
This works fine. They authorize the GitHub application tied to my organization's Auth0 account with its requested permissions without issue and land back in my application and I then have access to an Auth0 profile tied to their GitHub account, but then if I try and make an authenticated request to the GitHub API on their behalf:
var username = auth.nickname;
var repo = "some_user.github.io"; // todo: get repo from setup process
var url = "https://api.github.com/repos/" + username + "/" + repo + "/hooks/";
var conf = {
name: "web",
active: true,
config: {
"url": "https://webtask.it.auth0.com/api/run/wt-my-container_com-0/echo?webtask_no_cache=1",
"content_type": "json"
}
};
$http.post(url, conf).success(function(data, status) {
console.log("post successful:");
console.log(status);
console.log(data);
});
... GitHub rejects the request, either saying the request resource doesn't exist (to prevent private data leakage) or that I supplied bad credentials, depending on different variables (if I try supplying the "access_token" field provided in their Auth0 profile as a query param or supply my Auth0 application's client secret, etc).
I have scoured the documentation of both Auth0 and GitHub trying to figure out what the correct procedure is (for example, do I need to implement the whole OAuth2 token flow myself? it seems like Auth0 should be doing that for me) but nothing I have tried so far works, and nothing on Google has pointed me in the right direction. I have tried a number of other methods of doing this without success but I don't want to make this post too much longer. Any help would be greatly appreciated.
I figured it out. There were two problems: one, a trailing slash had crept in on the end of my API call to the GitHub endpoint, which evidently breaks something and causes GitHub to reject the request, and second, I had set things up to send along the Authorization header with every request as per the Auth0 guide here: https://auth0.com/docs/client-platforms/angularjs, specifically this part:
myApp.config(function (authProvider, $routeProvider, $httpProvider, jwtInterceptorProvider) {
// ...
// We're annotating this function so that the `store` is injected correctly when this file is minified
jwtInterceptorProvider.tokenGetter = ['store', function(store) {
// Return the saved token
return store.get('token');
}];
$httpProvider.interceptors.push('jwtInterceptor');
// ...
});
But GitHub does not like that since it does not contain the token it is expecting and will reject the request if it sees it. Once I removed the trailing slash and removed the above code, everything started working as expected.
Look at this gitHub page. It is something like this with angular:
//'common' will add the headder to every request.
$httpProvider.defaults.headers.common["Authorization"] = token YOUR_TOKEN;

Firebase AngularFire Facebook Login no login transports available error

I'm currently using Firebase's AngularFire and trying to login with some code I found in their documentation for facebook logins.
This is my html code (with ng-click to start login):
<a ng-click="loginWithFacebook()" class="btn btn-block btn-social btn-facebook">
This is what my angularjs code looks like (I've set up a login controller):
var app = angular.module("loginApp", ["firebase"]);
app.controller("loginCtrl", function($scope, $firebaseObject) {
var ref = new Firebase("firebaseUrl");
$scope.loginWithFacebook = function() {
ref.authWithOAuthPopup("facebook", function(error, authData) {
if (error) {
console.log("Login Failed!", error);
alert("That didn't work");
} else {
console.log("Authenticated successfully with payload:", authData);
document.write("You're logged in!");
}
});
};
So when I click, the button works except it keeps giving me this error message:
Error: There are no login transports available for the requested method.
at Error (native)
at yg (https://cdn.firebase.com/js/client/2.2.4/firebase.js:139:1271)
at https://cdn.firebase.com/js/client/2.2.4/firebase.js:160:141
I've taken a look in the documentation for firebase, and the error message and explanation is pretty cryptic and I have no idea what it means.
Could someone tell me whats going on and how I can be able login using Facebook and invoke a Facebook popup?
Just realized I still have this question unanswered:
I actually realized that it was merely because I didn't have a Web server set up to handle API calls to Firebase, it was a silly mistake on my part and I will leave this here for future Firebase users so that they understand that you would have to either use nodejs/rails or other backend frameworks to handle API calls or use something like Github Pages to just host your code online.

Resources