Google plus API shutdown, How it will affect Google auth2 login for web sites? - google-plus

I am confused with shutdown notification mails from Google one of the recent mail mentioned as
projects directly requesting the “plus.me” scope are affected. This scope may have been listed in some emails, even if not directly
requested by your project. We apologize for any confusion caused.
I am using following JS code for login, may I know will it affect anyway due to Google plus api shutdown?
<script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};HandleGoogleApiLibrary()" onreadystatechange="if (this.readyState === 'complete') this.onload()"></script>
<script type="text/javascript">
//google login starts
function HandleGoogleApiLibrary() {
// Load "client" & "auth2" libraries
gapi.load('client:auth2', {
callback: function() {
// Initialize client library
// clientId & scope is provided => automatically initializes auth2 library
gapi.client.init({
apiKey: 'API KEY HERE',
clientId: 'XXXXXXXXXXXXXXXXX.apps.googleusercontent.com',
scope: 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email'
}).then(
// On success
function(success) {
// After library is successfully loaded then enable the login button
//CODE AFTER SUCCESS
},
// On error
function(error) {
alert('Error : Failed to Load Library');
}
);
},
onerror: function() {
// Failed to load libraries
}
});
}
// Click on login button
$("#login-button").on('click', function() {
// API call for Google login
gapi.auth2.getAuthInstance().signIn().then(
// On success
function(success) {
// API call to get user information
gapi.client.request({ path: 'https://www.googleapis.com/plus/v1/people/me' }).then(
// On success
function(success) {
console.log(success);
var user_info = JSON.parse(success.body);
//VALIDATION
},
// On error
function(error) {
alert('Error : Failed to login');
}
);
},
// On error
function(error) {
$("#login-button").removeAttr('disabled');
alert('Error : Login Failed');
}
);
});

There is good news and bad news.
The good news is that you're not using any of the plus scopes.
The bad news is that you're using the plus API, which is also being shut down, and which was mentioned in a previous email that should have been sent to you.
Specifically, this chunk of code:
gapi.client.request({ path: 'https://www.googleapis.com/plus/v1/people/me' }).then(
calls the "plus.people.me" API.
Fortunately, you should be able to switch to a different API, such as the "userinfo" API, by changing endpoints to
https://www.googleapis.com/oauth2/v2/userinfo
You may also wish to look into the more modern People API, which works very similarly, and is slightly more complicated, but can provide other profile fields.

Related

Skype for web sdk signin issue with on prem use case

I am trying your samples and some very simple code for signing in. Status changes to Signing In. But it stays there and doesn't go to Signed In.
Following is my code :
var config = {
apiKey: 'a42fcebd-5b43-4b89-a065-74450fb91255', // SDK
apiKeyCC: '9c967f6b-a846-4df2-b43d-5167e47d81e1' // SDK+UI
};
var client;
$(function () {
'use strict';
Skype.initialize({ apiKey: config.apiKey }, function (api) {
client = new api.application();
// whenever client.state changes, display its value
client.signInManager.state.changed(function (state) {
$('p').text("Status : "+state);
});
}, function (err) {
console.log(err);
alert('Cannot load the SDK.');
});
$('#LogIn').click(function () {
// start signing in
client.signInManager.signIn({
username: $('#username').val(),
password: $('#password').val()
}).then(function () {
//log in worked!
$('p').text("Status : "+"Logged In");
}, function (error) {
//Something went wrong.
$('p').text("Status : "+error);
});
});
I installed Skype for Business desktop client and used same username and password and could sign in successfully. But with the above code, I am unable to sign in. Its staying at "signing In". I am not getting errors also. I also used your samples as per this article : https://msdn.microsoft.com/en-us/skype/websdk/docs/downloadrunsamples
But I saw the same issue. The spinning wheel is forever spinning. It looks like it is looking at the same status as my code and staying at signing in.
Please let me know what wrong I might be doing. Just starting with this SDK. Any suggestions for debugging also can help.

Auth0 callback URL mismatch

I am doing LinkedIn authentication with auth0 in a react app. I have set localhost:3000/upload in callback urls in settings, hopping that after users login at localhost:3000/login, they would be redirected to localhost:3000/upload. However, I always get this error: url localhost:3000/login is not in the list of callback urls. Why would auth0 expect to return to the page where you just logged in after logging in. Shouldn't it be some different url. It just does not make sense to me.
Edit:
export default class AuthService {
constructor(clientId, domain) {
// Configure Auth0
const options = {
allowedConnections: ['linkedin'],
auth: {
params: {responseType: 'code'}
}
};
this.lock = new Auth0Lock(clientId, domain, options)
// Add callback for lock `authenticated` event
this.lock.on('authenticated', this._doAuthentication.bind(this))
// binds login functions to keep this context
this.login = this.login.bind(this)
this.loggedIn = this.loggedIn.bind(this)
}
_doAuthentication(authResult){
// Saves the user token
console.log(authResult);
this.setToken(authResult.idToken)
this.lock.getProfile(authResult.idToken, (error, profile) => {
if (error) {
console.log('Error loading the Profile', error)
} else {
console.log(profile)
}
})
}
//....
Please ensure two things:
1). In your react app code
responseType: 'code'
2). On the Auth0 dashboard, under Settings -> Allowed Callback URLs put your callback entry (localhost:3000/upload) - which I think you have done but just in case.
Let me know if you are still having problems.
Make sure that there is no special hidden characters or space between the commas between the URLs when you paste it into the Auth0 Setting site. I didn't realise about this util I put every urls into Vim to check and see that there are such above cases
In the call to AuthProvider, make sure to use to same callback url as the one in Auth0 settings:
const uri='http://localhost:3000/upload';
<Auth0Provider
domain={domain}
clientId={clientId}
redirectUri={uri}>
To cause a redirect to a different URL after a successful authentication, you need to provide the redirectUrl to Lock, like this:
// Configure Auth0
const options = {
allowedConnections: ['linkedin'],
auth: {
responseType: 'code',
redirectUrl: 'http://localhost:3000/upload'
}
};
this.lock = new Auth0Lock(clientId, domain, options)
(Also notice that the responseType option goes under auth, not under auth.params.)
If you do the redirect, you won't reach the event handler you defined in your login page. You will need to either add an event handler in your destination page (and use responseType:token) or handle authentication results in your server code (this is what you will normally be doing if you are requesting a responseType: code).
the reason why you should set the callback Url in auth0 settings, because any one can use your client id and send request to google or linkedin, get the response to anywhere they set. but with this setting only you can access that response.
once your app is authorized to pull the data from linkedin, linkedin will send the data to where you specified. you should create a page to handle the response from Linkedin server. Let's name that page callback.js and this will be an example of response object.
accessToken: "hNuPLKTZHiE9_lnED0JIiiPNjlicRDp"
appState: null
expiresIn: 7200
idToken: "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik5FRXdSVUl5TURVeE4wSkJPRFZEUlRKRU1EVkZNemsxTXpNNU5VTXlNRGt6T0VWQlJqUkZRUSJ9.eyJodHRwOi8vbG9jYWxob3N0OjMwMDAvcm9sZSI6InNpdGVPd25lciIsImdpdmVuX25hbWUiOiJvbWFyIiwiZmFtaWx5X25hbWUiOiJpYm8iLCJuaWNrbmFtZSI6Im9tYXJpYm8xOTgyIiwibmFtZSI6Im9tYXIgaWJvIiwicGljdHVyZSI6Imh0dHBzOi8vbGg1Lmdvb2dsZXVzZXJjb250BQUFBQUkvQUFBQUFBQUFBQUEvQUNIaTNyLTEwLTEyVDIyOjU4OjAxLjgzM1oiLCJpc3MiOiJodHRwczovL3BvcnRmb2xpby15aWxtYXouYXV0aDAuY29tLyIsInN1YiI6Imdvb2dsZS1vYXV0aDJ8MTE0MDY0NTA2ODI2OTgwNTA5ODY3IiwiYXVkIjoiUEdVY242RjRRS21PRkJhb1k0UFdCeWpjVzIyT09vNGMiLCJpYXQiOjE1NzA5MjEwODIsImV4cCI6MTU3MDk1NzA4MiwiYXRfaGFzaCI6InN0R1l5SnJaMHNnbVYzSWNLWjlPeFEiLCJub25jZSI6InRrOV95b096enRmVThVVjFVMlVFR3IyMW5ORW5abjk4In0.TYS7mM8N2d7jEHFdWQGTSeAAUaDt4-0SMUG3LrcQ1r3xzY0RMGsUsEszj5xqk1GE0cIlFS10xCOYKsuHSwsFLomC1EbLjntjkledHtfD0MW84cMoXN6a-x-1-bNwl3lMYJ98qklTrNvTvkQJ6DWhei3hJ8rs8dnbNyCfckNVU6ptJU-9ef1DwWfHRomW5LQ6WSDRHZScW697gdgBEMU-Nd2SddyHhQe0kVh6lKdcbnskEAyCJLE07jfM40RQI_8LJouFcpoyImcXSDZlKv90tYfVDq9_TwE3GNaSz5I5snn0457oCgz0vuX0JoCUiaDuTIX7XiyXnozW_DxGMuhk4w"
idTokenPayload: {http://localhost:3000/role: "siteOwner", given_name: "me", family_name: "you", nickname: "nck", name: "nm", …}
refreshToken: null
scope: null
state: "xkEbffzXbdOYPLkXOUkrQeb0Jysbnlfy"
tokenType: "Bearer"
//THIS CODE IS FOR NEXT.JS9
//auth.js
class Auth0 {
constructor() {
this.auth0 = new auth0.WebAuth({
domain: "portfolio-ys.auth0.com",
clientID: "PGUWJQKmOFBaoY4PWByjcW22OOo4c",
redirectUri: "http://localhost:3000/callback",
responseType: "token id_token",
scope: "openid profile"
});
this.handleAuthentication = this.handleAuthentication.bind(this);
}
//there are too many methods are defined here i put only relevant ones
handleAuthentication() {
return new Promise((resolve, reject) => {
this.auth0.parseHash((err, authResult) => {
console.log(authResult);
if (authResult && authResult.accessToken && authResult.idToken) {
this.setSession(authResult);
resolve();
} else if (err) {
reject(err);
}
});
});
}
setSession function is where you set the cookies based on response object. I use js-cookie package to set the cookie.
setSession(authResult) {
const expiresAt = JSON.stringify(
authResult.expiresIn * 1000 + new Date().getTime()
);
Cookies.set("user", authResult.idTokenPayload);
Cookies.set("jwt", authResult.idToken);
Cookies.set("expiresAt", expiresAt);
}
}
const auth0Client = new Auth0();
export default auth0Client;
callback.js
import React from "react"
import auth0Client from "./auth0"
import {withRouter} from "next/router"
class Callback extends React.Component{
async componentDidMount(){
await auth0Client.handleAuthentication()
this.props.router.push('/')
}
render() {
return (
<h1>verifying logging data</h1>
)
}
}
export default withRouter(Callback) //this allows us to use router
I had similar issue "callback URL mismatch" and resolved it by running the application over https with a trusted certificate.
Here is a snippet from Auth0 applications settings section about callback URL, which says "Make sure to specify the protocol (https://) otherwisw the callback may fail in some cases."
If you're using the Android(Kotlin) SDK of auth0, I noticed that during runtime, the requested URL is being changed. e.g. app://{your_auth0_domain}/android/{package_name}/callback://{your_auth0_domain}/android/app://{your_auth0_domain}/android//callback
Originally URL was
app://{your_auth0_domain}/android/{package_name}/callback
and SDK is appending "://{your_auth0_domain}/android/app://{your_auth0_domain}/android//callback" this extra part.
Solution: Either put the same URL in auth0 setting dashboard as it showing in your logs
or
WebAuthProvider
.login(account)
.withScheme("app") // instead of complete URL, put only the remaining part from the URL,
.start(this, object : Callback<Credentials, AuthenticationException> {}
I hope it will definitely help android/app developer.

Ember simple-auth mixins deprected

I am an experienced (55+ years) programmer but a total noob in ember and js. I'm trying to get a simple authentication page working using the ember-cli addons ember-cli-simple-auth, ember-cli-simple-auth-oauth2 and cut-and-paste from the simplelabs tutorial.
I get the following in the console:
DEPRECATION: The LoginControllerMixin is deprecated. Use the session's authenticate method directly instead.
and:
DEPRECATION: The AuthenticationControllerMixin is deprecated. Use the session's authenticate method directly instead.
The solution may be trivial, but I have been chasing it for hours and get deep into javascript before reaching a dead-end. The code that is causing these errors is:
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
export default Ember.Controller.extend(LoginControllerMixin, {
authenticator: 'simple-auth-authenticator:oauth2-password-grant'
});
which invokes the ApplicationControllerMixin somewhere in the bower code.
Before I "re-invent the wheel" by translating some old html/ruby/pascal code into js, can anyone help me "Use the session's authenticate method directly instead."?
Thanks.
I feel you're pain. I spent weeks trying to sort this out. A big part of the problem is that so much has changed in the past couple of years and there are a lot of code examples out there that are outdated or don't work together. It's really difficult to put the various pieces together coherently, and figure out what one does NOT need to do.
That said, please keep in mind that i'm a n00b as well. What i've done seems to work ok but i've no idea whether there's a much better way.
Also, what you're trying to do may not be the same as what i've done. My app authenticates against google (and twitter, fb, etc.) using Simple-Auth-Torii and then exchanges the returned Authenication Code for an Authentication Token. That last part happens on the server. So, after the session authenticates, i then pass the auth code to the server and get back the auth code.
// routes/login.js
import Ember from "ember";
import ENV from "../config/environment";
export default Ember.Route.extend({
setupController: function(controller, model) {
controller.set("errorMessage", null);
},
actions: {
googleLogin: function() {
var _this = this;
// Using "session's authenticate method directly" right here
this.get("session").authenticate("simple-auth-authenticator:torii", "google-oauth2")
.then(function() {
// We're now authenticated. The session should now contain authorization
// code from provider. We now need to exchange that for an auth token.
var secureData = _this.get("session.content.secure");
// call server to initiate token exchange from provider
var exchangeData = {
authorizationCode: secureData.authorizationCode,
redirectUri : secureData.redirectUri,
provider : 'google'
};
// sends ajax request to server, which will in turn call provider
// with authentication code and receive auth token
_this.tokenService.fetch(exchangeData).then(function(response) {
if (response.success) {
_this.set("session.content.secure.access_token", response.data.token);
_this.set("session.content.secure.userData", response.data.user);
// take user somewhere ...
_this.transitionTo("data_sets");
}
else {
// set an error message, log the response to console, whatever, but
// we need to invalidate session because as far as simple-auth
// is concerned we're already authenticated. The following logs the user out.
_this.get("session").invalidate();
}
}, function(error) {
console.log("tokenService.fetch error", error);
_this.get("session").invalidate();
});
}, function(error) {
console.log("simple-auth-authenticator:torii error", error);
_this.get("session").invalidate();
});
},
twitterLogin: function() {
// etc.
}
}
});
Logging a user out also uses the session directly.
{{!templates/application.hbs}}
<ul class="nav navbar-nav navbar-right">
{{#if session.isAuthenticated}}
<li><button {{ action 'invalidateSession' }} class="btn btn-sm">Logout</button></li>
{{/if}}
...
</ul>
// routes/application.js
import Ember from "ember";
import ENV from "../config/environment";
import ApplicationRouteMixin from "simple-auth/mixins/application-route-mixin";
export default Ember.Route.extend(ApplicationRouteMixin, {
actions: {
// action is globally available because in application route
invalidateSession: function() {
// the most basic logout
this.get("session").invalidate();
return;
// If you need to invalidate also on the server do something like:
//
// var _this = this;
// return new Ember.RSVP.Promise(function(resolve, reject) {
// var params = {
// url : ENV.logoutEndpoint,
// type : "POST",
// dataType : "json"
// };
// Ember.$.ajax(params).then(function(response) {
// console.log('session invalidated!');
// console.dir(response);
// _this.get("session").invalidate();
// });
// });
}
}
});
I've met the same deprecation problem. I thinks this snippet for a lovely login controller will do, it's a bit more what you asked, but I hope it is still understandable. I use it with devise, it's almost the same except I use it this way: authenticate('simple-auth-authenticator:devise', credentials)
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
authenticate: function() {
// identification and password are the names of the input fields in the template
var credentials = this.getProperties('identification', 'password');
if (!credentials.identification || !credentials.password) {
return false;
}
this.get('session').authenticate('simple-auth-authenticator:oauth2-password-grant', credentials).then(function() {
// authentication was successful
}, function(errorMessage) {
// authentication failed
});
}
}
});

Facebook login with Torii and Simple-Auth : no authentication data returned

I tried to setup a facebook login using Torii and Simple-Auth Torii authenticator. I am using ember-cli.
Here is my configuration :
// config/environment.js
ENV['torii'] = {
providers: {
'facebook-oauth2': {
apiKey: 'my facebook app id'
}
}
}
Here is my login code :
// app/controllers/login.js
import Ember from 'ember';
import LoginControllerMixin from 'simple-auth/mixins/login-controller-mixin';
export default Ember.Controller.extend(LoginControllerMixin, {
actions: {
authenticateWithTorii: function(){
this.get('session').authenticate(
'simple-auth-authenticator:torii',
'facebook-oauth2'
).then(
function(data) {
alert('SUCCESS ' + data);
},
function(error) {
alert('There was an error when trying to sign you in: ' + error);
}
);
}
}
});
The popup is opening asking for authorization, then I see the alert with "SUCCESS UNDEFINED". I thought I will get some data I could use on my backend to definitely authentify the user (access token or facebook uid, etc...).
Did I miss something in the way to use Torii with Simple-Auth ?
The promise returned by Session#authenticatedoes not have a value but everything that the torii authenticator resolves with is available via the session as soon as that's authenticated (which it is in your case as the returned promise has resolved). You could access e.g. a token property with
var _this = this;
this.get('session').authenticate(
'simple-auth-authenticator:torii',
'facebook-oauth2'
).then(function(data) {
alert('SUCCESS ' + _this.get('session.token'));
})
You can also inspect the session's content property (which you shouldn't use otherwise as it's private but for debugging that's ok) to find out what's available:
console.log(this.get('session.content'))

Ember.js Ember Simple Auth persist authentication information in LocalStorage does not work

I use Ember Simple Auth with the following settings:
Note: I use Ember App Kit.
app.js
// init Ember.SimpleAuth
App.initializer({
name: 'authentication',
initialize: function(container, application) {
Ember.SimpleAuth.setup(application, { // #todo at version 0.1.2 of Ember-simple-auth, add container variable
crossOriginWhitelist: ['http://customdomain'],
// store: Ember.SimpleAuth.Stores.LocalStorage, // default now
authenticationRoute: 'article.login'
});
}
});
export
default App;
a simple loginController
(took it mostly from Ember App Kit Simple Auth)
var CustomAuthenticator = Ember.SimpleAuth.Authenticators.OAuth2.extend({
serverTokenEndpoint: 'http://customdomain/access_token/',
makeRequest: function(data) {
return Ember.$.ajax({
url: this.serverTokenEndpoint,
type: 'POST',
data: {
grant_type: 'password',
username: data.username,
password: data.password
},
dataType: 'json',
contentType: 'application/x-www-form-urlencoded'
});
}
});
var LoginController = Ember.Controller.extend(Ember.SimpleAuth.LoginControllerMixin, {
authenticator: CustomAuthenticator,
actions: {
// display an error when logging in fails
sessionAuthenticationFailed: function(message) {
console.log('sessionAuthenticationFailed');
this.set('errorMessage', message);
},
// handle login success
sessionAuthenticationSucceeded: function() {
console.log('sessionAuthenticationSucceeded');
this.set('errorMessage', "");
this.set('identification', "");
this.set('password', "");
this._super();
}
}
});
export
default LoginController;
So far so good, I can authenticate a user thought a login form. However when I press F5, I have to login again. The LocalStorage adapter is empty. So the question is what do I need to persist the token and session?
Note: I cannot update to ember-simple-auth 0.1.2, bower cannot find the new version. Seems that the github version of https://github.com/simplabs/ember-simple-auth-component is not up to date.
Edit:
I have updated my code as follows:
app.js
// init Ember.SimpleAuth
App.initializer({
name: 'authentication',
initialize: function(container, application) {
Ember.SimpleAuth.Authenticators.OAuth2.reopen({
serverTokenEndpoint: 'http://customdomain/access_token'
});
Ember.SimpleAuth.setup(container, application, { // #todo at version 0.1.2 of Ember-simple-auth, add container
crossOriginWhitelist: ['http://customdomain'], // #todo remove when live
// store: Ember.SimpleAuth.Stores.LocalStorage,
authenticationRoute: 'article.login'
});
}
});
export default App;
loginController:
var LoginController = Ember.Controller.extend(Ember.SimpleAuth.LoginControllerMixin, {
// authenticator: CustomAuthenticator, // not needed anymore
actions: {
// display an error when logging in fails
sessionAuthenticationFailed: function(message) {
this.set('errorMessage', message);
},
// handle login success
sessionAuthenticationSucceeded: function() {
this.set('errorMessage', "");
this.set('identification', "");
this.set('password', "");
this._super();
}
}
});
export default LoginController;
I haven't used the oauth2 authenticator before (just a custom one for my backend that I wrote) but I think the same concepts should apply.
When you refresh the page ember-simple-auth makes a call to the restore method of the oauth2 authenticator that you are using. The restore method is looking for a property called 'access_token' to confirm that the user has already authenticated with your server. Does your REST API return a property called access_token when you authenticate with the endpoint at http://customdomain/access_token/? If not, you want to make sure this is happening or you will encounter the refresh issue you're having. Here's the restore method in the oauth2 authenticator provided with ember-simple auth:
restore: function(properties) {
var _this = this;
return new Ember.RSVP.Promise(function(resolve, reject) {
// It looks for the 'access_token' property here which should have been set
// by the authenticate method if you returned it from your REST API
if (!Ember.isEmpty(properties.access_token)) {
_this.scheduleAccessTokenRefresh(properties.expires_in,
properties.expires_at,
properties.refresh_token);
resolve(properties);
} else {
reject();
}
});
}
Additionally, I think in your sessionAuthenticationSucceeded action you need to return true. Otherwise the action won't propagate up to the ember-simple-auth ApplicationRouteMixin (unless you are not using that mixin or don't depend on its sessionAuthenticationSucceeded method in which case it doesn't matter).
This should be fixed with 0.1.2: github.com/simplabs/ember-simple-auth/releases/tag/0.1.2
I also just updated github.com/simplabs/ember-simple-auth-component