In my application, I implemented Google signout using jsapi.
I used the url https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=xxxxxx to connect to Google and then https://www.googleapis.com/plus/v1/people/xxxxxx to get user data from google profile.
Now I need to signout the user from Google while clicking a button from my application. How can I implement this in JavaScript, or at least it must ask the Google login page every time the user signs in.
I have tried approval_prompt=force, but seems not to be working.
Overview of OAuth: Is the User Who He/She Says He/She is?:
I'm not sure if you used OAuth to login to Stack Overflow, like the "Login with Google" option, but when you use this feature, Stack Overflow is simply asking Google if it knows who you are:
"Yo Google, this Vinesh fella claims that vinesh.e#gmail.com is him, is that true?"
If you're logged in already, Google will say YES. If not, Google will say:
"Hang on a sec Stack Overflow, I'll authenticate this fella and if he can enter the right password for his Google account, then it's him".
When you enter your Google password, Google then tells Stack Overflow you are who you say you are, and Stack Overflow logs you in.
When you logout of your app, you're logging out of your app:
Here's where developers new to OAuth sometimes get a little confused... Google and Stack Overflow, Assembla, Vinesh's-very-cool-slick-webapp, are all different entities, and Google knows nothing about your account on Vinesh's cool webapp, and vice versa, aside from what's exposed via the API you're using to access profile information.
When your user logs out, he or she isn't logging out of Google, he/she is logging out of your app, or Stack Overflow, or Assembla, or whatever web application used Google OAuth to authenticate the user.
In fact, I can log out of all of my Google accounts and still be logged into Stack Overflow. Once your app knows who the user is, that person can log out of Google. Google is no longer needed.
With that said, what you're asking to do is log the user out of a service that really doesn't belong to you. Think about it like this: As a user, how annoyed do you think I would be if I logged into 5 different services with my Google account, then the first time I logged out of one of them, I have to login to my Gmail account again because that app developer decided that, when I log out of his application, I should also be logged out of Google? That's going to get old really fast. In short, you really don't want to do this...
Yeh yeh, whatever, I still want to log the user out Of Google, just tell me how do I do this?
With that said, if you still do want to log a user out of Google, and realize that you may very well be disrupting their workflow, you could dynamically build the logout url from one of their Google services logout button, and then invoke that using an img element or a script tag:
<script type="text/javascript"
src="https://mail.google.com/mail/u/0/?logout&hl=en" />
OR
<img src="https://mail.google.com/mail/u/0/?logout&hl=en" />
OR
window.location = "https://mail.google.com/mail/u/0/?logout&hl=en";
If you redirect your user to the logout page, or invoke it from an element that isn't cross-domain restricted, the user will be logged out of Google.
Note that this does not necessarily mean the user will be logged out of your application, only Google. :)
Summary:
What's important for you to keep in mind is that, when you logout of your app, you don't need to make the user re-enter a password. That's the whole point! It authenticates against Google so the user doesn't have to enter his or her password over and over and over again in each web application he or she uses. It takes some getting used to, but know that, as long as the user is logged into Google, your app doesn't need to worry about whether or not the user is who he/she says he/she is.
I have the same implementation in a project as you do, using the Google Profile information with OAuth. I tried the very same thing you're looking to try, and it really started making people angry when they had to login to Google over and over again, so we stopped logging them out of Google. :)
You can log out and redirect to your site:
var logout = function() {
document.location.href = "https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=http://www.example.com";
}
For me, it works (java - android)
void RevokeAcess()
{
try{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("https://accounts.google.com/o/oauth2/revoke?token="+ACCESS_TOKEN);
org.apache.http.HttpResponse response = client.execute(post);
}
catch(IOException e)
{
}
CookieManager.getInstance().removeAllCookie(); // this is clear the cookies which tends to same user in android web view
}
You have to call this function in AsyncTask in android
To logout from the app only but not the Gmail:
window.gapi.load('auth2', () => {
window.gapi.auth2
.init({
client_id:
'<Your client id configired on google console>'
})
.then(() => {
window.gapi.auth2
.getAuthInstance()
.signOut()
.then(function() {
console.log('User signed out.');
});
});
});
I'm using above in my ReactJs code.
You can simply Create a logout button and add this link to it and it will utimately log you out from the app and will redirect to your desired site:
https://appengine.google.com/_ah/logout?continue=http://www.YOURSITE.com
just toggle YOURSITE with your website
This works to sign the user out of the application, but not Google.
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
});
Source: https://developers.google.com/identity/sign-in/web/sign-in
Ouath just makes the Google instance null, hence it you out of Google. Now that's how the architecture is made. Logging out of Google, if you Logout of your app is a dirty work, but can't help if the requirement stipulates the same. Hence add the following to your signOut() function. My project was an Angular 6 app:
document.location.href = "https://www.google.com/accounts/Logout?continue=https://appengine.google.com/_ah/logout?continue=http://localhost:4200";
Here localhost:4200 is the URL of my app. If your login page is xyz.com then input that.
this code will work to sign out
<script>
function signOut()
{
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
auth2.disconnect();
});
auth2.disconnect();
}
</script>
I hope we can achieve this by storing the token in session while logging in and access the token when he clicked on logout.
String _accessToken=(String)session.getAttribute("ACCESS_TOKEN");
if(_accessToken!=null)
{
StringBuffer path=httpRequest.getRequestURL();
reDirectPage="https://www.google.com/accounts/Logout?
continue=https://appengine.google.com/_ah/logout?
continue="+path;
}
response.sendRedirect(reDirectPage);
It looks like Google recently broke something with their revoke stuff (it's started returning 400 errors for us). You now have to call
auth2.disconnect();
In our case we then have to wait a couple of seconds for the disconnect call to complete otherwise the sign-in code will re-authorise before it's done. It'd be good if google returned a promise from the disconnect method.
If any one want it in Java, Here is my Answer, For this you have to call Another Thread.
1. Try this code, if you are using onSignIn() function
2.
<script src="https://apis.google.com/js/platform.js?onload=onLoad" async defer></script>
<script>
function signOut() {
onLoad();
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
if(auth2.isSignedIn)
{
auth2.isSignedIn.set(false);
}
});
}
function onLoad() {
gapi.load('auth2', function() {
gapi.auth2.init();
});
}
</script>
Related
I'm integrating Google sign-in to my web app, but no matter what I specify, it always shows a warning in the login flow:
To continue, Google will share your name, email address, and profile picture with [app name].
I don't need or want the name, email address, or profile picture of my users; I just need a token_id. I'm aware of a similar question where the developer wants only the email address, and it is explained that the other details can be derived from the email address anyway, but in this case I don't want the email address either.
Following the documentation I've set:
function login() {
gapi.auth2.init({
client_id: myClientIdHere,
cookie_policy: 'none',
fetch_basic_profile: false, // <-- remove basic profile
scope: 'openid', // <-- request only openid
ux_mode: 'redirect', // <-- using redirect to avoid popup blocker issues
redirect_uri: myRedirectUriHere,
}).then((GoogleAuth) => {
GoogleAuth.signIn() // [etc]
});
}
function init() {
gapi.load('auth2', login);
}
Inspecting network requests shows that this is directing the user towards:
https://accounts.google.com/o/oauth2/auth?redirect_uri=[myRedirectUri]&response_type=permission%20id_token&scope=openid&openid.realm=&client_id=[myClientId]&ss_domain=[myDomain]&fetch_basic_profile=false&gsiwebsdk=2
Which looks correct. I've tried tweaking that URL and manually navigating to it and no matter what I change it always seems to show the warning.
In my Google API console project under Credentials -> OAuth consent screen -> Scopes for Google APIs, I can see that "email", "profile" and "openid" are all listed, and I can't find any option to remove them.
I don't know if it's actually sending me that information when a user signs in, but I'd like to remove the warning from the login screen.
How can I use Google sign-in just for sign-in? How do I prevent it giving me profile / email address information?
When you get an access token back from Google, you can call the userinfo endpoint and obtain user profile information using the openid scope, so even though you don't need the email and profile information, you can still obtain that information through the userinfo endpoint [1].
[1] https://developers.google.com/identity/protocols/OpenIDConnect#obtaininguserprofileinformation
I'm using OWIN with ASP.Net Identity to enable users to log in to a site using their social media credentials.
As part of this we also request extra permissions for interacting with their account.
This is working fine for Twitter and Facebook for the most part, except when trying to log out from the site when using Facebook for the log in.
If you log out of the ASP.Net app you are still logged in to Facebook. That's not a problem in itself, but when you return to the ASP.Net app you're automatically logged in using the Facebook account you used before and you're given no chance to choose a different account.
As the user you can navigate to Facebook, log out, then return to the ASP.Net app and you'll get asked to log in again, but that's not a very nice process for the user to go through. Simply explaining that to a user will be messy and there's plenty for them to get wrong (logging out in a different browser, not reading the help text, etc).
An answer on this question suggests using the javascript SDK which isn't too awful to implement: Logging out from facebook when using MVC 5 OWIN
Some of the answers say "that's how it's supposed to work", but we expect our users to be using multiple accounts with this application so a reasonable log out process is required. Also Facebook themselves say we should log people out of Facebook when logging out of our application: https://developers.facebook.com/docs/facebook-login/web#logout
Note: This function call will also log the person out of Facebook. The reason for this is that someone may have logged into your app and into Facebook during the login flow. If this is the case, they might not expect to still be logged into Facebook when they log out of your app. To avoid confusing people and to protect personal security, we enforce this logout behavior.
But that bring me to the current issue I'm encountering.
I have the following Typescript/Javascript code which performs the log out:
FB.getLoginStatus((getLoginStatusResponse) => {
if (getLoginStatusResponse.status === 'connected') {
FB.logout((logoutResponse) => {
$("form[id='logoutForm']").submit();
});
} else {
$("form[id='logoutForm']").submit();
}
});
getLoginStatus returns fine saying that the user is logged in (status === 'connected') === true.
But then, when I make the logout call I can see the API returns a 302 Not Found, and the redirect points to the facebook home page.
The Facebook Javascript SDK handles this by swallowing the error and not calling the logout callback.
Why am I getting a 302 for an official API call made when I have confirmed the user is logged in?
And is there another way to achieve the log out? A server-side solution would be perfect! Although I don't want to use anything that's undocumented/unsanctioned.
I have an MVC 5 web app that has facebook authentication set up and working nicely. User clicks "Facebook" on the login page, signs in to Facebook and that authenticates with our web site. If the user logs out, the call to AuthenticationManager.SignOut() logs out of the web site correctly, but if the user then goes back to the login page and clicks "Facebook" again they are immediately signed in without having to sign in to facebook.
So my question is, how do I configure MVC 5 OWIN facebook login so that the user is signed out of facebook when they sign out of the web site, or to put it another way, prevent caching of the authentication for the next sign in. I don't want a users facebook login to be silently cached in case they are sharing a browser with other users.
The only way that I know to do this would be to tie an event to your log out button or link and use the Facebook Javascript SDK to actually perform the Facebook logout for you.
LogOut
<script type="text/javascript">
$(function(){
$("#Logout").on("click", function(e){
if(confirm("This will also log you out of Facebook. Proceed?")){
FB.logout(function(response) {
// Person is now logged out
});
}else{
//do not allow the link to continue and sign our of your site.
//This is optional and allows you to provide options
e.PreventDefault();
}
});
});
</script>
You could actually use the confirm dialog to ask if they want to be signed out of Facebook as well. A confirm would mean yes, a not confirm would mean no, just sign me out of your site. Again, using the SDK and a little bit of control logic should provide the results you need.
You can't. To do so would require being able to access cookies set by facebook.com which is explicitly forbidden for security reasons: you can only access cookies on your own domain. The login with Facebook is separate from your application. The user isn't truly logging into your site. They're logging into Facebook and Facebook is simply verifying the user identity with your site. If you're truly concerned you can put a message on your sign out page reminding them to sign out of Facebook as well.
You could try recreating Facebook's log out code (doing a post to the same action they use with the same data they send). But, I'm almost positive they'll be employing some sort of CSRF protection on that, so it probably won't work.
Saw this thread and wanted to add to it, to help the masses.
In the guidance, "Code! MVC 5 App with Facebook, Twitter, LinkedIn and Google OAuth2 Sign-on" from Microsoft, it has the following section buried in it:
Logging off your App and Logging in With Another Account
If you log on to your app with Facebook, , and then log out and try to log in again with a different Facebook account (using the same browser), you will be immediately logged in to the previous Facebook account you used. In order to use another account, you need to navigate to Facebook and log out at Facebook. The same rule applies to any other 3rd party authentication provider. Alternatively, you can log in with another account by using a different browser.
So this behavior is by design.
To learn more about OWIN, hear is some good reading:
http://www.asp.net/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server
http://brockallen.com/2014/01/09/a-primer-on-external-login-providers-social-logins-with-owinkatana-authentication-middleware/
Have more links to share, but drats, reputation is not high enough yet. :)
Its been two years and If OpenID Connect is used, then a solution exists as
// POST: /Account/LogOff
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
Request.GetOwinContext().Authentication.SignOut();
return Redirect("/");
//AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
//return RedirectToAction("Index", "Home");
}
If it possible to force a re-authorization (I.E asking for username and password) from the LinkedIn oauth api?
Usecase:
To protect sensitive data, in case someone forgets to log out, some actions on our site can only be taken after you re-verify yourself with your password (even when logged in). We allow login using LinkedIn, in which case the user does not have a separate password on our site. In this case we would like to force a re-authorization (username/password) from the LinkedIn api so that user can still confirm his identity.
The important issue here is that it cannot just accept because the user is already logged in on LinkedIn and has accepted to app, this would not provide any level of security for someone who has forgotten to log out, it has to explicity ask for authorization by password again.
There is no way to force re-asking of the OAuth username/password once the user has logged in other than to log them out of LinkedIn first.
You can see this in action by opening your LinkedIn JSAPI-enabled site and having the user 'Sign in with LinkedIn'. Once you have completed the initial OAuth sign-in/authorization, open a tab in the same browser and go to linkedin.com - you will also have been logged into the site.
In your case, if the user simply walks away from the computer leaving the browser open, they will still be logged into both of your site AND linkedin.com. Closing the browser, or logging out via the API or the linkedin.com site will solve this.
One strategy might be that any access to 'sensitive' data generates a logout, which will clear the cookies but not the app authorization, and then to instantiate the auth dialog:
IN.User.logout();
IN.UI.Authorize().place();
Details here. I've tested this and it seems to work well.
You can do a logout call when a user wishes to logout from your site,
simply make them call an iframe request to https://www.linkedin.com/secure/login?session_full_logout=&trk=hb_signout and return a successful signout message when that happens. Sounds dodgy (xss attack) but this is probably the only non-intrusive way of logging the user out.
Here's a small jQuery plugin that I wrote to help accomplish this.
First, add a data-hidden-iframe attribute to your standard "Sign Out" in your application.
Sign out
Note that the data-hidden-iframe attribute value points at the LinkedIn logout URL that Ernest recommended.
Next, add this jQuery plugin to load a hidden iframe with the LinkedIn logout URL. It will wait until the iframe is fully loaded before propagating back to default click behavior.
$(document).ready ->
$("[data-hidden-iframe]").loadhiddenIframeBeforeClick()
$.fn.loadhiddenIframeBeforeClick = ->
this.on "click.iframe", ->
return if $(this).data("already-iframed")
event.preventDefault()
event.stopPropagation()
href = $(this).data("hidden-iframe")
$(this).data("already-iframed", true)
$("<iframe style='display:none;'>").attr("src", href).appendTo("body").load =>
$(this).trigger("click")
For those that cannot read CoffeeScript, here's the equivalent JavaScript:
$(document).ready(function() {
return $("[data-hidden-iframe]").loadhiddenIframeBeforeClick();
});
$.fn.loadhiddenIframeBeforeClick = function() {
return this.on("click.iframe", function() {
var href,
_this = this;
if ($(this).data("already-iframed")) return;
event.preventDefault();
event.stopPropagation();
href = $(this).data("hidden-iframe");
$(this).data("already-iframed", true);
return $("<iframe style='display:none;'>").attr("src", href).appendTo("body").load(function() {
return $(_this).trigger("click");
});
});
};
I know this is an old question in which I am answering.. But it can help someone to get out of this problem
There is a solution I have recently implemented just create a fake webview call with the actual logout url for linkedin that is
https://www.linkedin.com/secure/login?session_full_logout=&trk=hb_signout
Just call the above url with a fake webview, incase of iOS it could be
UIWebView *webView=[[UIWebView alloc] initWithFrame:CGRectZero];
NSURLRequest *req=[NSURLRequest requestWithURL:[NSURL URLWithString:#"https://www.linkedin.com/secure/login?session_full_logout=&trk=hb_signout"]];
webView.delegate=self;
[webView loadRequest:req];
Hope it helps someone..
If you want to force the user to re-login with their Linked In credentials, then just take them through the authorization process again. However, it will have to be the entire authorization process with Linked In requesting the user to authorize your application and you storing a new OAuth token.
I am about to start a new project building a web UI with a lot of different functionality. Part of the functions however include the ability to update and access certain social media sites - Facebook and Twitter primarily.
I would like the user to login to the system and then also have the ability to manage multiple FB/Twitter accounts so that they can interact with these all from one place without having to authenticate every time they go to do something. For security reasons I obviously don't want to store passwords, but I'm not sure how to go about this one.
I know it's possible - does anyone have any pointers on how to go about this?
FYI - I'm programming in PHP, Javascript/Jquery. Thanks in advance!
Here is the Facebook part. A good and easy way to do that is to use the Facebook PHP SDK (see on github). So you will have something like :
require "facebook.php";
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
$user = $facebook->getUser();
If the user is logged in, then $user is his Facebook ID. You then have to check if you have a valid access token by making an API call :
If it does not raise any exception, then you have a valid access token
If it does, then you have to re-authenticate the user.
Here you go :
if ($user) {
try {
$facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
You need then to display the login or logout link :
<?php if ($user): ?>
Logout of Facebook
<?php else: ?>
Login with Facebook
<?php endif ?>
When the user is logged in and you have a valid access token, you can make API calls to get data from Facebook :
$user_profile = $facebook->api('/me');
You may want to check the example page of the Facebook PHP SDK which is well documented.
Hope that helps.