Angularjs + nodejs + passport cross domain request - node.js

I'm using passport with facebook strategy for authentication. Problem doesn't reside in the back-end which is nodejs, as i have tested without angularjs and everything works just fine, but whenever angularjs comes into play i'd get CORS error.
Access-Control-Allow-Origin header is present on the requested resource. Origin host:8000 is therefore not allowed access.
I have tried most of the solutions i have found via google, but nothing has really worked so far. Does anyone have an idea what might be wrong?
This is the most common answer usually to this sort of question as far as i understand.
site.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
And like i said, it is not nodejs fault.

You'll need to use a popup to get around the CORS issue with Angular.. see this post for an example: http://www.webdeveasy.com/single-page-application-authentication/

Related

Setting up Swagger Ui in Firebase Functions Server

I've developed an API on Firebase Cloud Functions and I want to include a docs path to it.
I'm using swagger and I could successfully test it locally (localhost:PORT/docs) but when I deploy the function to Firebase it's not working, it redirects me to an authorization page.
I think I figured out why this is:
Let's say the name of my Cloud function is cfunc. Then the base url for it is something like https://region-name-project-name.cloudfunctions.net/cfunc. Based on how I included the swagger documentation:
const swaggerDoc = require('./docs/swagger.config.json')
app.use(
'/docs',
allowCors,
swaggerUi.serve,
swaggerUi.setup(swaggerDoc, {
customCssUrl: '/assets/swagger.css',
customSiteTitle: 'My Function Title',
customfavIcon: '/assets/logo.ico',
swaggerOptions: {
supportedSubmitMethods: [] //to disable the "Try it out" button
}
})
)
the docs should be located at https://region-name-project-name.cloudfunctions.net/cfunc/docs. When I try to access that URL, watching "Network" in my browser DevTools, it attempts a GET at that URL with response 304 and then redirects to https://region-name-project-name.cloudfunctions.net/docs and that's what brings up the Google Authentication page, since there's no Cloud Function named "docs" so Google thinks I'm trying to access something else in Firebase Cloud Functions (the same thing happens if I do something like https://region-name-project-name.cloudfunctions.net/tomato)
But I still don't know how to fix this redirect or why it's happening. I tried adding the Cloud Function URL to the host parameter of the swagger.config.json file, and some modifications to CORS, like allowing more Request Methods, adding json as content type, allowing authentication on headers, but nothing seems to be working.
Hope I was clear enought, if not tell me any other info you need (it's one of my first posts here :B)
Found the SOLUTION
After testing a BUNCH of different things, I found out that the redirection was in fact happening always removing one slice of the path after, for example I changed the docs endpoint to '/something/docs' and when accessing the URL that would be https://region-name-project-name.cloudfunctions.net/cfunc/something/docs it redirected to https://region-name-project-name.cloudfunctions.net/cfunc/docs which did not bring up the Google Authentication thing but now wasn't a valid path for my docs so it returned a 'Cannot GET /cfunc/docs'.
For some reason this redirection DOES NOT happen if you add an extra forward slash ('/') at the end of the documentation URL. So, in the first case, where the endpoint for the documentation is only '/docs', accessing the URL https://region-name-project-name.cloudfunctions.net/cfunc/docs/ does it. I do not know why that is, I'm probably posting an Issue on the swagger repo, but if someone has some extra data on why or how to make it work otherwise it would be awesome to hear.
Hope this helps someone else!
EDIT:
Oh and another thing I forgot, it's apparently better if you setup swagger-ui as if you were using express Router, even if you are not (maybe Firebase loads the Cloud Function with something like a router), so instead of app.use('/docs', swagger-ui.serve, swagger-ui.setup(swagger-file)) do app.use('/docs', swagger-ui.serve) and then app.get('/docs', swagger-ui.setup(swagger-file))

Electron + Vue + msal-nodejs + Azure Ad: redirect URL issue

I'm building a desktop app using Electron and Vue as framework.
I also need to authenticate the user using Azure AD and I'm using msal-node.js as library to do that.
I'm able to authenticate with the server in azure and get the user info, but I cannot figure it out how to set the redirect URL.
First I have to say that the behaviour between dev and prod change drastically and I'm going to explain both scenarios and, in both of them I'm going to use history mode or not
DEV - using createWebHistory
Return Url in Azure and .env file: http://localhost:8080/
This is what I've got from the devTools during the normal navigation (no authenticated)
And this is what I've got after the authentication (the call to the API is successful):
Blank page in the app.
DEV - using createWebHashHistory
Return Url in Azure and .env file: http://localhost:8080/#/
After the authentication (failed):
Blank page in the app.
PROD
In prod I must use createWebHasHistory otherwise I've got blank page from the beginning.
The first problem I've got in production is the url itself.
When I create the window I call the following url:
await win.loadURL('app://./index.html')
In azure I cannot use the same url because it's not a valid url.
If I use just:
await win.loadURL('app://index.html')
I've got blank page
Any idea?
Thank you
The solution I've found it's pretty simple. Probably it's not the most "elegant", but it works, at least for prod. In dev I've still got the same weird problem described above.
Basically I'm starting a node server (localhost:3031 for example), within the app itself, then I'm catching the redirect url with it (localhost:3031/redirect) and serving the internal url from it:
expressApp.get('/redirect', async (req, res) => {
await win.loadURL('app://./index.html#about')
})
As I said, it works and I don't see any security issue with that, but, if you have any other idea or suggestion, please let me know.
Thank you
UPDATE
I've found the issue with Dev as well. In order to authenticate I'm using what Microsoft is suggesting in its documentation.
If you look at the file AuthProvider.js there is this portion of code, at the beginning:
const CUSTOM_FILE_PROTOCOL_NAME = process.env.REDIRECT_URI.split(':')[0];
Down below, in the method "getTokenIteractive" there is this other piece of code that applies the new protocol:
protocol.registerFileProtocol(CUSTOM_FILE_PROTOCOL_NAME, (req, callback) => {
const requestUrl = new URL(req.url)
callback(path.normalize(`${__dirname}/${requestUrl.path}`))
})
In Dev my REDIRECT_URI is "http://localhost:3031/redirect", but the app protocol must be "app" (or whatever you have chosen) in order to work with Vue. So, I've just wrapped this last method in a condition based on the environment and now everything works as expected everywhere.
I hope all this can be useful to someone.
I ran into a similar issue and your solution helped me out, thank you! Can I ask how you handled the logout redirect?
Also have you tried onBeforeRequest to handle the redirects, instead of a node server?
It was used as an example in an auth0 blog: https://auth0.com/blog/securing-electron-applications-with-openid-connect-and-oauth-2/

SameSite Cookie attribute issue

I have a web application with react in front-end and node in backend.
I am using passport authentication with passport-saml strategy. Since the last browser update i am seeing an issue. Once I try to login I was taken to the authentication page and it returned back to app page again, then auth page and this continues. looks like i was in a redirection loop.
Once I disabled the samesite attribute flag in chrome then the issue got resolved.
I read some articles and realized that the samesite attribute is causing this. (please correct me if i am wrong. Also want to know), where we will be adding this in backend.. I was using node express session module and addded a cookie object as :-
cookie: {sameSite: 'none', secure: true}
Can someone please help me to find a solution for this?
Is you application behind proxy server with ssl enabled?
I had a similar problem with similar setup and similar symptoms, but I've already switched from saml to oauth (without using passport), so I'm not sure if this helps you.
Anyway, there were two things I needed to do to keep a session cookie 'alive' over the requests.
Set 'trust proxy' in your server code: app.set('trust proxy', 1)
Set X-Forwarded-Proto header to proxy server config (mine is nginx):
location / {
proxy_set_header X-Forwarded-Proto $scheme;
...
}
I'm not sure this is your case, but I'm assuming your app is deployed (I haven't faced this issue in localhost, so your problem may be somewhere else) and your session is being set.
After 3 days trying to figure It out. I finally found a way around this issue, It's not a fix, I'm quite sure PassportJS will come with a solution for that eventually, but for now It allowed me to get the user from the authentication.
Since we are not being able to get the user from the cookie, but the information is in the server session, the way to get this information is to add to the 'server.js' a route to get the user directly from the server session:
app.get('/api/getUser', (req, res) => {
res.json(req.session.user);
});
For some reason, I suppose the lack of cookie somehow, using the req.session inside of a router is returning undefined, but If used inside 'server.js' (or your server index file) It gets the session.
If you need the req.user._id or some other sensitive information for other requests, I would recommend returning a jwtToken with this information to the frontend (in res.json), then save the token directly in localStorage and pass the token in the body of your requests, is not the ideal, but It's the safer way I could think to keep the ids safe.

Express Route.post issue

I use Express for my back-end application. But I have the problem Why there is not any problem on signup route, but when server starts it crashes with following error.
The place it identifies as source of error is signin route. But, what is the difference between signin and signup here. I can't figure out.
Check if your AuthenticationController.signin is defined. Try doing console.log(AuthenticationController.signin) and see if it is defined. I guess most probably typo issue. May be it's AuthenticationController.signIn notice capital I.

How can I test (integration-testing) with supertest a Node.js server with Passport JS using facebook/google... strategies with OAUTH2?

I have a Node Js application and I'm integration-testing my app with supertest/superagent + nockjs.
I have a problem, because I want to test my login rest apis using supertest to REPLY with a FAKE PROFILE RESPONSE + token for example for facebook/google/github and so on. (I'm not interested in LocalStrategy, because it' very simple)
How can I do that?
I'm trying with GitHub, and I wrote this code (not working) absolutely wrong, probably very stupid without any sense...It was an experiment XD.
nock('https://github.com/login/oauth')
.get('/authorize?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fapi%2Fauth%2Fgithub%2Fcallback&scope=user%3Aemail&client_id=XXXXXXXXXXXXXXXXXXXX')
.reply(302,undefined,
{
location : "http://localhost:3000/api/auth/github/callback?code=ab7f9823f03071209b26"
}
)
.get('http://localhost:3000/api/auth/github/callback?code=ab7f9823f03071209b26')
.reply(200, responseMocked);
PS: probably I made a mistake with url and status, I don't know.
Also, where I should set the connection.sid's cookie ?
How can I fix/rewrite this code to be able to integration-testing my application?
I'm also interested to use passportjs stub/mock, but I want a library supported and well documented.
UPDATE: I fixed the name of the mocked profile object (responseMocked)
Thank you,
Stefano.

Resources