google provider sign in with supabase auth - authentication

sigining in with next_auth and a google provider sends me to the "site URL configuration" setting.
(the main site URL)
with an access token at the end of the URL.
Siging in on the same page with normal means works fine.
I am using the supabse "nextjs auth helpers"
I have everything working normally outside of google.
I have everything set up correctly according to the youtube videos and docs after checking over and over a few times.
after reaching the page:
https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?
in which you choose your google account.
the redirect after goes to the redirect emails send you to, but does not have the person logged in.
I cant figure out why this is, the token should have been used to log in.
const [supabaseClient] = useState(() =>
createBrowserSupabaseClient(
process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
)
has just been corrected to :
const [supabaseClient] = useState(() =>
createBrowserSupabaseClient({
supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL,
supabaseKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,
})
);

Related

MSAL + SvelteKit route protection

I have an application with SvelteKit + MSAL, my authentication page works fine, and authenticate all users without error. My login button is on my main page (http://localhost:3000). The authentication with MSAL works fine, after the authentication, its redirected to the page (http://localhost:3000/home).
I logged out from all my accounts in my browser, and when I tried to access my home page, through http://localhost:3000/home, I could access it without any authentication. I though that could be some error with cache, then I went to another PC, and did the same test and I was able to reach my home page without authentication. I looked for route protection with MSAL, but I couldn't find anything related with MSAL.Not sure if I missed something or any settings on my MSAL.js. I am using MSAL-browser. I want the user to be authenticated in all my routes.
export async function protectedRoute() {
let name = msalInstance.getAccountByHomeId.length;
if (name == 0) {
goto("/");
}
}
This is the code I have tried to use but it didn't work, I was trying to get the lenght of my users logged in, and if it was zero to redirect to the login page. I tried to use the same logic to get the name but its not showing the name of the users on my MSAL instance.
Thanks

Firebase functions auth.generateEmailVerificationLink() generating link with wrong apiKey

I have a Firebase functions project with dev and prod versions. There I'm using auth.generateEmailVerificationLink() to send email verification for a newly created user. Everything works well except in prod environment (testing locally or hosted) the apiKey in the link generated by auth.generateEmailVerificationLink() is not same as Firebase's default apiKey. And clicking that link I get the page with error code:
Try verifying your email again
Your request to verify your email has expired or the link has already been used
Note that when I get the link with the wrong apiKey, if I change it to the right apiKey. the verification works. So it seems the whole problem is related to the wrong apiKey in generated email verification link.
Also to note that the wrong apiKey is not random key but used in project front end for Google Maps apis.
The code itself is simple. (I'm leaving out code which creates user etc as those parts all work perfectly)
-Initializing Admin SDK:
import { initializeApp } from 'firebase-admin/app';
import { getAuth } from 'firebase-admin/auth';
initializeApp();
const auth = getAuth();
export { auth };
-Generating email verification email
const sendEmail = async () => {
const actionCodeSettings = {
// This url is working correctly, it is the same as in Firebase console
// and when changing the wrong apiKey to correct redirecting works correctly
url: process.env.DOMAIN as string,
};
await auth
.generateEmailVerificationLink(email, actionCodeSettings) // email is the email of newly created user
.then((link) => {
// generate email message with link
// generate mailOptions
// use transporter to send email
});
};
Thank you for any help
EDIT
I tested deleting that "wrong" apiKey from GCP credentials page and replaced it with another. Then running the function locally everything worked normally but the "wrong" is still in the verification email link even tho it doesn't exist anymore.
Firebase strongly recommends that if Admin SDK is used in Cloud Functions, among others, initializing the app should be done without parameters.
https://firebase.google.com/docs/admin/setup#initialize-without-parameters
For me it seems something is for some reason pulling that "wrong" and now even deleted apiKey from somewhere to usage.
I solved this by noticing that, unlike in dev project, Web Api Key (Project Settings>General) is different than Web App's firebaseConfig apiKey.
So I added correct permission to this Web Api Key (Identity Toolkit API is required for email verification email) found in GCP credentials and now the cloud function sends email verification emails with correct and working apiKey.

How do I get react-native-inappbrowser-reborn to trigger success upon successful Facebook login

I'm trying to setup a manual flow for Facebook login, as per the docs at: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/
I've got my test Facebook app working as expected, i.e., I can login using a private web browser window fine. The URL I'm using is:
https://facebook.com/v3.3/dialog/oauth?client_id=<app_id>&display=popup&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html
Now within my React-Native app, I'm using react-native-inappbrowser-reborn to present a SFAuthenticationSession on iOS. As per their docs (at https://www.npmjs.com/package/react-native-inappbrowser-reborn), I'm doing the following:
const redirectUri = "https://www.facebook.com/connect/login_success.html"
const url = "https://facebook.com/v3.3/dialog/oauth?client_id="+appId+"&display=popup&response_type=token&redirect_uri=https://www.facebook.com/connect/login_success.html"
InAppBrowser.isAvailable()
.then(() => {
InAppBrowser.openAuth(url, redirectUri, {
// iOS Properties
dismissButtonStyle: 'cancel',
// Android Properties
showTitle: false,
enableUrlBarHiding: true,
enableDefaultShare: true,
})
.then((response) => {
// Only gets to this point if user explicitly cancels.
// So this does not trigger upon successful login.
})
// catch handlers follow
Using the above, my app correctly open up an in-app browser and I can login fine using a test user for my test app. Upon successful login though, I don't get redirected back to the .then completion handler. It just stays in the in-app browser view and I see the same message from Facebook that I see when logging in using a web browser. It says something like "Success. Please treat the url the same as you would a password", or something like that.
I may be missing something here, but I thought the purpose of passing redirectUri as an argument to openAuth was so that upon redirection to that URI, the completion handler would be triggered.
Question: How do I redirect back to the completion handler upon login success?
I think that you already have a solution but thought it might be useful for someone else facing this issue. If you don't have a solution so far follow my instructions:
You can't directly redirect back to your application using deep link, since Facebook will not call a link `like myapplicationname://mycustompath´. It's only possible to call links using the https-protocol (https://...).
The solution I'd suggest you to use is to redirect using your own API (Facebook -> Your API -> Deep Link Redirection). You will understand why this is required in the most of the real world applications at the end of the instructions.
Starting from your react-native app call the authorize endpoint of Facebook with a redirection to your application and set the global deeplink of your app as redirect uri.
InAppBrowser.close();
InAppBrowser.openAuth("https://graph.facebook.com/oauth/authorize?client_id=YOURCLIENTID&redirect_uri=https://YOURDOMAIN:PORT/auth/facebook", "{YOURAPPSDEEPLINKNAME}://{SOMEPATHYOUWANTTOEND}")
.then((response) => {
handleAuthorized(response, LOGINTYPE.FACEBOOK);
});
Now after login you'll be redirected to your API with the authorization code token as query parameter (e.g. https://YOURDOMAIN:PORT/auth/facebook?code=AVERYLONGCODESENTBYFACEBOOK)
Using this code token from the query parameter, you make another API Call to get the access_token for the user
{GET}: https://graph.facebook.com/v15.0/oauth/access_token?client_id=YOUR_CLIENT_ID&redirect_uri=https://YOURDOMAIN:PORT/auth/facebook&client_secret=YOUR_CLIENT_SECRET&code=AVERYLONGCODESENTBYFACEBOOK
Facebook's API will send you an answer as JSON with the access_token inside.
You can make another call using the access token of the user, to get the userId and the username
{GET}: https://graph.facebook.com/me?access_token=ACCESS_TOKEN_SENT_BY_FACEBOOK_IN_PREVIOUS_GET_REQUEST.
If you need the e-mail address for the user you have to make another call. Make sure you'd set the permission to read the e-mail address for your app on the developer portal of facebook.
The following request will return you the id, name and the email of the user
{GET}: https://graph.facebook.com/USERIDFROMPREVIOUSREQUEST?fields=id,name,email&access_token=ACCESSTOKEN
I think you want to save all these information to a database and create a session in order to keep the user logged in and therefore all the requests described will be useful for you in a real application.
After doing all the backend stuff, you're ready for the redirection using deep link. To do that, set a meta-tag to redirect the inappbrowser to your application:
<meta http-equiv="refresh" content="0; URL={YOURAPPSDEEPLINKNAME}://{SOMEPATHYOUWANTTOEND}" />

loopback protected routes/ensure login

How do I ensure that a user is logged in before I render a view using loopback?
I can loggin in the front end using my angular app. But I wanted to block anonymous users from viewing the page.
I thought it would be a header, something like headers.authorization_token, but it does not seem to be there.
I am looking for something like connect-ensurelogin for passport, without having to use passport.
This is the $interceptor that solves your problem.
This code detects 401 responses (user not logged in or the access token is expired) from Loopback REST server and redirect the user to the login page:
// Inside app config block
$httpProvider.interceptors.push(function($q, $location) {
return {
responseError: function(rejection) {
if (rejection.status == 401) {
$location.nextAfterLogin = $location.path();
$location.path('/login');
}
return $q.reject(rejection);
}
};
});
And this code will redirect to the requested page once the user is logged in
// In the Login controller
User.login($scope.credentials, function() {
var next = $location.nextAfterLogin || '/';
$location.nextAfterLogin = null;
$location.path(next);
});
Here is one possible approach that has worked for me (details may vary):
Design each of the Pages in your Single Page Angular App to make at one of your REST API calls when the Angular Route is resolved.
Secure all of your REST API Routes using the AccessToken/User/Role/ACL scheme that LoopBack provides.
When no valid Access Token is detected on the REST Server side, pass back a 401 Unauthorized Error.
On the Client Side Data Access, when you detect a 401 on your REST Call, redirect to your Logic Route.
For the smoothest User Experience, whenever you redirect to Login, store the Route the User wanted to access globally
(localStore, $RootScope, etc.) and redirect back there when the User
Logs in and gets a valid Access Token.
Here is the LoopBack Access Control sample: https://github.com/strongloop/loopback-example-access-control

Rails: Google OAUTH2, sending post request properly

I am building a web app requiring access to a users gmail using Oauth2. I registered my app and can get the initial code, but can't figure out how to get an access token and refresh code afterwards.
First, the user is sent to a secure google page to put in user name/password. Afterwards, google redirects the user to something like:
127.0.0.1/oauth2callback?code=4/ux5gNj-_mIu4DOD_gNZdjX9E
I have this method below to handle the redirect. The code is sent with other info in a post request back to Google in exchange for a access token and refresh code. Unfortunately the response in the bottom has blank body. What am I doing wrong? Do I need to call another function on response to get the access token?
def oauth2callback
require "uri"
require "net/http"
uri = URI.parse("https://accounts.google.com/o/oauth2/token")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(
{'code'=>params[:code],
'client_id' => CLIENT_ID,
'client_secret' => CLIENT_SECRET,
'redirect_uri' => '127.0.0.1:3000/oauth2callback',
'grant_type' => 'authorization_code'})
http.use_ssl = true
response = http.request(request)
#response.body() is blank
end
Your redirect uri must match exactly the one, the user got redirected to. In your case this is 127.0.0.1/oauth2callback without :3000.
However, I believe that for Google both uri's needn't to be identical, but at least defined in the developer console, so maybe you could try adding 127.0.0.1:3000/oauth2callback to your developer console.