Authenticate with facebook

It does not work:

commit:

my app id setup:

error message I recieve:

Hello there,

I have never used the Facebook APIs, but I know many authentication-related APIs do not accept requests from http (non-secured). So, the authentication cannot be tested through a localhost URL, and must be tested on a live domain with https.

Hope this helps

1 Like

they have an ‘in development switch/ live deployment switch on top of their dashboard’ that makes it confusing.

so you are implying I have to put it somewhere with https and update this site URL:

Ive tried another way and the console messages give me a bunch of error messages, and one of them coincides with what your suggesting:

this commit:

can you recommend a way to test it on a local environment? ngrok
Is there a quick way like some plugin I can down load for vscode?

This means If I put it on an https like you say it will return the user name and profile picture to use on the dashboard

Yeah, that looks about what I was thinking.

I am not sure what you could do. In the past, I have just tested by hosting my app on Heroku, and updating the callback URL (website URL) to match what Heroku uses.

also can you please explain some things that dont make sense to me.

It says its a login button. How is a user supposed to be able to log in if hes not even signed up yet? or should I write that logic myself

for example Ive written this for a login if he didnt have a social account, but it assumes he already exists in the db…

session_start();

require_once "pdocon.php";

if (isset($_POST['submit']) && !empty($_POST['submit'])) { // Handle the form.
    if (!empty($_POST['email']) && !empty($_POST['password'])) {
        $stmt = $db->prepare("SELECT user_id, email, is_confirmed, fname, lname ,user_level FROM tbl_users WHERE email=:email AND password=:password");
        $stmt->execute(array("email" => $_POST["email"], "password" => $_POST["password"]));
        if ($stmt->rowCount() >= 1) {
            //this means user with a matching password
            $_SESSION["email"] = $_POST['email'];
            $row = $stmt->fetch();
            $_SESSION["user_id"] = $row["user_id"];
            $_SESSION["fname"] = $row["fname"];
            $_SESSION["lname"] = $row["lname"];
            $_SESSION["user_level"] = $row["user_level"];
   
            $host = $_SERVER['HTTP_HOST'];
            $uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
            $extra = 'admin/dashboard.php';
            echo $host;
            echo '</br>';
            echo $uri;
            echo '</br>';
            $exploded = explode("/", $uri);
            print_r($exploded);
            echo '</br>';
            echo $exploded[1];
            header("Location: http://$host/$exploded[1]/$extra");

        } else {
            echo 'he filled in the fields but it was wrong no match ';
        }
    } else {
        echo 'empty fields';
    }
}

so what I want to know is how does the whole social login fit into this? because it says social login, not social sign up. should I allow a user to also sign up for an account with social?

and if for example he signed up regularly using just an email and passowrd and comes back another time wants to use social how will i know to match that with what he was before?

and similarly, if he signs in one time with facebook and another time he uses twitter, how will I match those

whatif for example when he signs up I set a local storage on his machine to something that was returned in the response… that could work to match those things? just thinking out loud…

These are decent questions, and I am not sure I could give satisfactory answers.

The way I understand it:

  • Many sites do not want to have to deal with the security of storing personal user-secret information. - not entirely accurate, as you still need to store personal information, but do not have to deal with passwords, and typical login routes.
  • Thus, an easy way out is to make use of popular platforms who have already done the dirty work. That is, many internet users already have a Facebook account, which already has a uniquely identifiable data source per user.
  • I, as a developer/lesser-website, make it so a user can sign-in to their already-created FB account, and Facebook let me know (by means of a success message) that the user is someone Facebook know.
  • I take the details Facebook send back (e.g. id, name, photo), and store that in my database. (these details DO NOT come from the user).
  • Any other data I want to associate with a specific user, I just add to the user document on my database.
  • Next time the user wants to log in, they go through Facebook again, I check the data returned if it matches anything in my database. If yes, I approve the user access to the account which matched. If not, a new user is created in my database, again, based off of what Facebook told me about them that is uniquely identifiable.

Local storage only makes sense for a few situations, because it will not persist to the next session (unless the user is on the same machine, browser, and has not cleared their browser storage).

I hope this is somewhat clear.

I got most of my understanding, by working my way through the freeCodeCamp Advanced Node and Express section. Specifically, this is taught in:
Advanced Node and Express - Implementation of Social Authentication | Learn | freeCodeCamp.org - and the lessons which follow but I highly recommend doing the whole section, else you will not be able to pass the tests.

how can you say I wont have to deal with passwords? what if the user does not have a social account? I know many poeple that dont use facebook twitter, instagram etc

what you are describing above does not sound like a complete login system.+ signup

This is a business and UX decision. This is why many platforms have not just FB as an authentication strategy, but 2+.

Authentication strategies like FB, GitHub, Instagram, offer more advantages than just helping developers not necessarily needing to deal with passwords. Example, the auth strat often provides additional information which can be used to pre-populate user account data (profile picture, location, email…)

I am not telling you you should not have a login/password system. I am just saying auth strategies bypass this system.

Take freeCodeCamp as an example. On the /learn platform, there is no option what-so-ever to input a password. The login options are: Email (OTP), GitHub, Google (IIRC), and one other (i think). This serves 2 purposes - less development hassle, and, were freeCodeCamp to be ‘hacked’, and all account data released, no one could use the information to get into any Camper’s accounts (on any platform) - if done correctly. There is an article somewhere describing why this decision was made by fCC

Hope this clarifies.

Found the article:
360 million reasons to destroy all passwords (freecodecamp.org)

Free Code Camp is getting rid of passwords. We’re going to start just sending you a magic link when you want to sign in for the first time on a new device.

Magic link, currently its a one time passcode…
for that you would generate a code and save it along with the user in db and when he confirms his account you keep him, otherwise hes never confirmed his account so you could delete him. with magic link you could just have that generated code sent to him as a parameter in the linke… and your handler on the page would check that and confirm him

I do see sign up with password on the freecodecamp website. but true not on the /learn platform

if I understnad this correctly the piece of info that is used to identify someone reguardless of how he signs up or signs in is email address

It is working as expected… However… What im thinking to do is the following logic:

I dont want to create a seperate profile if a user logs in using a different authentication. As long as the email is the same and hes been authenticated he should use the same profile.

Example: Some apps, you sign in using plain email/password combo, next time it prompts you to sign in and you didnt remember and then you use gmail or facebook, it doesnt matter. anyways the app creates an entirely new profile for you and your starting over from step one. But I dont agree with that, i think its a bad user experience. I would like to say that as long as the email is the same I want them to have access to the same data they set up prior.

social authentication in this repo is working as expected, however there is the following thats still unclear:

if you register with a user using a different method, or using email and password but its the same email as using a method that you previously registered with. It crashes.

I understand, I mean I can fix that but…

this line:

if i change that logic to say that if there is a user but the password does not match then just give the user access to the data anyways…

(fyi password here, im just using the second part of this string, I beleive it changes depending on the method you use to sign in)
sub

problem if I do what im saying, that route… anyone can hit it and youll just need to know an email address… not so good.

there is this hoc sort of thing they have here:
protected route but it just protects that page, I dont think it protects the route:

They have a jwt middleware, I mistakenly tried to use it inside the class but it did not work becuase its hook. Do i have to convert that whole todo component to stateless to use it or maybe i can just create a seperate functional component with the getAccessTokenSilently and use it in the class that way instead… although ive not tried it yet…

Ive found this article and this article,
but im thinking if I just use the jwt then I dont have to, please advise the simplest way to achieve what im aiming to do. I hope I explained myself clearer now.

Edit: todo file for reference

This is what my first thought would be:

  • If user uses SA first (to register)
    • Store email address (as well as whatever else userdata needed)
    • Store token for future logins
    • If user decides on another login method (e.g. Email/Pwd):
      • Check if email matches existing
      • Store password, and send an email with verification
      • DO NOT give access to account, until they have verified (they can verify via previously logged-in method, or via email verification link)
  • If user uses Email/Pwd first (to register)
    • Store email address with whatever else
    • Store password (hashed)
    • Verify user via email
    • If SA is used to login:
      • Match email
      • Store necessary information in same document.

I am not sure if that helps in anyway, but I would assume there are many tools out there which already handle this.

1 Like

thank you so much for your reply, thing is, I dont believe I have access to passwords.

I am using the unique user identifier to save as a “password” its mentioned here at this timetamp:

unique identifier video timestamp

however, that will change if the user uses a different login method.

What i am looking for is a way that if hes authenticated through their API that I can get an identifier that would Not change. So as long as its the same email, I want to get something that is the same identifier.

In the video they discuss using a jwt middleware, its in the repo in the server file as well. But i did not see anything in our curriculum on using JWTs, nor do I know if I can even use it to generate the same token as long as the email is the same. Now Im guessing I cant do it with that.

for reference, here is the timestamp where they discuss that:
video timestamp

I see a similar question on their forum I am reading it now to see if it contains a solution I can implement:

although I dont really care if there is multiple users in their system only I want a way to link these multiple users from their end to a single account on my end…
If the answer is contained in your description above, I apologize as ive not understood.