Move to another hbs in ember after the authentication is done - facebook

I have an app in which I have include a fb login.I am using ember-simple-auth for authorization and session manganement.I am able to authenticate the user and move to my "feed" hbs .The problem is when I open the app on another tab it is rendering the login page.How do I implement where if the user is authenticated it directly move to "feed" hbs.Similary to facebook,instagram where user login for the first time and after that they are redirect to feed page until they logout.
autheticator.js
const { RSVP } = Ember;
const { service } = Ember.inject;
export default Torii.extend({
torii: service('torii'),
authenticate() {
return new RSVP.Promise((resolve, reject) => {
this._super(...arguments).then((data) => {
console.log(data.accessToken)
raw({
url: 'http://example.com/api/socialsignup/',
type: 'POST',
dataType: 'json',
data: { 'access_token':'CAAQBoaAUyfoBAEs04M','provider':'facebook'}
}).then((response) => {
console.log(response)
resolve({
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
access_token: response.access_token,
// jscs:enable requireCamelCaseOrUpperCaseIdentifiers
provider: data.provider
});
}, reject);
}, reject);
});
}
});
router.js
import Ember from 'ember';
import config from './config/environment';
var Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('index',{path:'/'});
this.route("aboutus",{path:'/aboutus'});
this.route('feed',{path:'/feed'});
});
export default Router;

You need to use the application-route-mixin.js in the route that will be the first shown after login and authenticated-route-mixin.js for all the routes that need to be logged to see them. Check this example for further information.

Related

Get token set on API on a SSR page Nextjs

I am using Spotify authentication and in the callback I set the cookie and redirect to another page:
export default async (req, res) => {
const token = await getToken(req.query.code);
res.setHeader('Set-Cookie', cookie.serialize('token', JSON.stringify(token), {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: token.expires_in,
sameSite: 'strict',
path: '/',
}));
res.redirect(token ? '/cloner' : '/');
}
On '/cloner' page I do SSR where '/' is the path to the login page:
export async function getServerSideProps(ctx) {
const cookies = nookies.get(ctx);
if (!cookies.token) { // <-- is undefined
return {
redirect: {
destination: '/',
permanent: false,
}
}
}
return {
props: {}
}
}
In the getServerSideProps the token is undefined so is returning me to the login page ('/').
BUUUUUUT, if I check in the site I can see the cookie, and if I write the /cloner manually that page load just right.
If you check in the link below you will see that if you login redirect to login again. But, if you refresh the login page it sends you to the cloner page (in login I have also SSR to redirect to cloner if already login)
https://playlist-cloner.vercel.app/

How could i pass cookies in Axios

I am in a next-js app and my auth token is stored in cookies.
For some raisons i use Swr and Api route to fetch my secured api backend.
i am trying to find a way to put my auth token in all api request.
During login cookie is set
res.setHeader(
'Set-Cookie',
cookie.serialize('token', data.access_token, {
httpOnly: true,
secure: process.env.NODE_ENV !== 'development',
maxAge: data.expires_in, // 1 week
sameSite: 'strict',
path: '/',
}),
);
This is an example of a page using swr fetch
//page/test.ts - example of my test route
const { data, error } = useFetchContent(id);
if (error) {
showError('error');
replace('/');
}
return <DisplayContent content={data} />
This is a swrFetchHook
// fetchContentHook
function useFetchContent(id: string): ContentDetail {
return useSWR<any>(`/api/content/${id}`, fetcherApiRoute);
}
const fetcherApiRoute = (url: string): Promise<any> => {
return axios(url)
.then((r) => r.data)
.catch((err) => {
console.info('error is ', err)
throw err
});
};
export default useFetchContent;
inside api route
export default async (req, res): Promise<ContentDetail> => {
const { id } = req.query;
if (req.method === 'GET') {
const fetchRealApi = await apiAxios(url);
if(fetchRealApi) {
// here depending on result of fetchRealApi i add some other fetch ...
return res.status(200).json({ ...fetchRealApi, complement: comp1 });
}
return res.status(500)
}
return res.status(500).json({ message: 'Unsupported method only GET is allowed' });
};
and finally api axios configuration
const apiAxios = axios.create({
baseURL: '/myBase',
});
apiAxios.interceptors.request.use(
async (req) => {
// HERE i am trying to get token from cookies
// and also HERE if token is expired i am trying to refresh token
config.headers.Authorization = token;
req.headers['Content-type'] = 'application/x-www-form-urlencoded';
return req;
},
(error) => {
return Promise.reject(error);
},
);
export default apiAxios;
I am stuck here because i cant find token during apiAxios.interceptors.request.use...
Did you know what i am doing wrong, and am i on a correct way to handle this behavior ?
To allow sending server cookie to every subsequent request, you need to set withCredentials to true. here is the code.
const apiAxios = axios.create({
baseURL: '/myBase',
withCredentials: true,
});
Nilesh's answer is right if your API is able to authorize requests based on cookies. Also it needs the API to be in the same domain as your frontend app. If you need to send tokens to the API (the one which is in the cookie), then you will need a small backend component often called BFF or Token Handler. It can extract the token from the cookie and put in an Authorization header.
At Curity we've created a sample implementation of such a Token Handler, of which you can inspire: https://github.com/curityio/kong-bff-plugin/ You can also have a look at an overview article of the Token Handler pattern.

ember-simple-auth facebook authenticator

Trying to hook up facebook authentication for my app. I've got the backend working correctly but my authenticator (I think this is the problem) is always returning undefined.
Copying the example from from ember-simple-auth the console log on line 23 is never called, making me think something else the issue?
import Ember from 'ember';
import Torii from 'ember-simple-auth/authenticators/torii';
const {inject: {service}} = Ember;
export default Torii.extend({
torii: service(),
ajax: service(),
authenticate() {
const ajax = this.get('ajax');
return this._super(...arguments).then((data) => {
return ajax.request('http://localhost:8080/api/login', {
type: 'POST',
dataType: 'application/json',
data: {
'grant_type': 'facebook_auth_code',
'auth_code': data.authorizationCode
}
}).then((response) => {
console.log("CALLED!");
return {
access_token: response,
provider: data.provider
};
});
});
}
});
The response from the server is the access_token from facebook;
How can I better debug/solve what's going on here?
The problem was actually a simple error with the dataType used. It should be dataType: 'json' not dataType: 'application/json'

Meteor + facebook login (loginWithFacebook) issue. client_id is always undefined in login popup's URL

I put this issue in gist as well:
https://gist.github.com/yhagio/7561f34d12bc5edb9b5fe0fc1b4bb2b6
Github Repo : https://github.com/yhagio/meteor-tatter
Issue
When I click facebook login button, it opens the login popup, but
the URL in the popup always shows that client_id=undefined, and gives "Sorry, something went wrong".
I installed service-configuration and accounts-facebook meteor packages and configured as follows.
Also, cretead the app & added Facebook Login product in https://developers.facebook.com
Am I missing something?
Screenshot
The URL is like this:
https://www.facebook.com/v2.2/dialog/oauth?client_id=undefined&redirect_uri=http://localhost:3000/_oauth/facebook&display=popup&scope=public_profile&state=eyJsb2dpblN0eW...
In server https://github.com/yhagio/meteor-tatter/blob/master/imports/startup/server/index.js
import { Meteor } from 'meteor/meteor';
import { clientId, secret } from './secret.js';
Meteor.startup(() => {
ServiceConfiguration.configurations.upsert(
{ service: "facebook" },
{
$set: {
clientId: clientId,
loginStyle: "popup",
secret: secret
}
}
);
});
In client https://github.com/yhagio/meteor-tatter/blob/master/imports/ui/helpers/auth.js
import { Meteor } from 'meteor/meteor';
export default function auth() {
return new Promise((resolve, reject) => {
Meteor.loginWithFacebook({
requestPermissions: ['public_profile']
}, (err, user) => {
if (err !== null) return reject(err);
resolve(user);
});
});
}
Problem was that it should be appId instead of clientId. Even though the guide shows clientId. Ref: http://docs.meteor.com/api/accounts.html#service-configuration

Custom authenticator with Ember simple auth + Ember CLI

I'm trying to write a custom authenticator, similar to the one from this example in the docs. The goal is to be able to retrieve the currently logged in user via session.user.
I'm using Ember CLI, so in initializers/authentication.js I have
import Ember from 'ember';
var customAuthenticator = Ember.SimpleAuth.Authenticators.Devise.extend({
authenticate: function(credentials) {
debugger;
}
});
export default {
name: 'authentication',
initialize: function(container, application) {
Ember.SimpleAuth.Session.reopen({
user: function() {
var userId = this.get('user_id');
if (!Ember.isEmpty(userId)) {
return container.lookup('store:main').find('user', userId);
}
}.property('userId')
});
// register the custom authenticator so the session can find it
container.register('authenticator:custom', customAuthenticator);
Ember.SimpleAuth.setup(container, application, {
routeAfterAuthentication: 'landing-pages',
authorizerFactory: 'ember-simple-auth-authorizer:devise'
});
}
};
When I try to authenticate, I get the following error:
TypeError: Cannot read property 'authenticate' of undefined
at __exports__.default.Ember.ObjectProxy.extend.authenticate
Any idea why?
As of Simple Auth 0.6.4, you can now do something like:
index.html:
window.ENV['simple-auth'] = {
authorizer: 'simple-auth-authorizer:devise',
session: 'session:withCurrentUser'
};
initializers/customize-session.js:
import Ember from 'ember';
import Session from 'simple-auth/session';
var SessionWithCurrentUser = Session.extend({
currentUser: function() {
var userId = this.get('user_id');
if (!Ember.isEmpty(userId)) {
return this.container.lookup('store:main').find('user', userId);
}
}.property('user_id')
});
export default {
name: 'customize-session',
initialize: function(container) {
container.register('session:withCurrentUser', SessionWithCurrentUser);
}
};
You would need to do something like this:
Em.SimpleAuth.Authenticators.OAuth2.reopen
serverTokenEndpoint: "http://myapp.com/token"
authenticate: (credentials) ->
new Em.RSVP.Promise (resolve, reject) =>
data =
grant_type: "password"
username: credentials.identification
password: credentials.password
#makeRequest(data).then (response) =>
# success call
, (xhr, status, error) ->
# fail call
What I think might be happening is that you are registering the authenticator with the application and not the authenticator itself?
The problem is that the AMD build does not currently automatically register the extension libraries' components (see https://github.com/simplabs/ember-simple-auth/issues/198). I'll change that in the next release and will probably also adopt the documentation to be more focussed on the AMD build instead of the browserified version. For the moment you'd have to run this in your initializer
container.register(
'ember-simple-auth-authorizer:devise',
Ember.SimpleAuth.Authorizers.Devise
);
container.register(
'ember-simple-auth-authenticator:devise',
Ember.SimpleAuth.Authenticators.Devise
);