How can i send jwt token to client after OAuth autherization?

Viewed 458

I am trying to authenticate user with GitHub OAuth and for regular users i am using jwt tokens.

In my flow , the user press the button "Login with github" and after that by follow the Github docs - user redirect to github web for choose his account.

So this is my main code for my client side:

function SocialLogin(props) { 

    const githubAuth = async (e) =>{
        e.preventDefault()
        const githubOAuthURL = 'http://localhost:5000/api/oauth/github';
        let githubTab = window.open(githubOAuthURL, '_self');
        githubTab.focus();
    }  

  return (
    <div>
        <div className="right-box-inner"></div>
        <div className="wrap-buttons">
            <div className="signwith">Sign in with Social Network</div>
            <button onClick={githubAuth} className="social github"><i className="fab fa-github"></i>    Log in with Github</button>
        </div>
    </div>
  )
}

In my server side, the route "api/oauth/github" that the client asks for, is:

router.get('/github', async (req,res) => {
    try{
    res.redirect('https://github.com/login/oauth/authorize/?client_id='+config.get('githubClientId'))
    }
    catch(err){
        console.log(err.response)
    }
})

so after https://github.com/login/oauth/authorize/?client_id='+config.get('githubClientId') is exectued ,and the correcrly choose his account , the callback url as i defined in my app settings at githubaccount, executed:

router.get('/github/callback', async (req,res) => {
    const {query} = req;
    const code = query.code;
    try{
        if(!code)
          return res.status(404).json({msg : 'Autherization failed'})
        else{
          const gitAuthDetails = {
            client_id: config.get('githubClientId'),
            client_secret: config.get('githubSecret'),
            code: code
            
        }
          const headers = {
            headers: {
                'Content-Type': 'application/json;charset=UTF-8',
                "Access-Control-Allow-Origin": "*",
            }
          }
          const response=await axios.post('https://github.com/login/oauth/access_token',gitAuthDetails,headers)
          access_token=response.data.split('=')[1].split('&')[0]

          const userResponse=await axios.get('https://api.github.com/user',{ headers: { Authorization: 'token ' + access_token } })

          //Lets asssume that i store here a new user to my DB with the all github details e.g username, email ...
          // and create a payload for jwt.
          // Now i want to generate new JWT for the new user , and problem is here. to where i need send my token? 
          // there is any function in my client side that listening and waiting for response.
            jwt.sign(
                payload,
                config.get('jwtSecret'),
                {expiresIn:360000},
                (err,token) => {
                    if(err) throw err;
                    //What i need to do with my token?
                    res.redirect('http://localhost:3000/dashboard')
                }
            );


        }
    }
    catch(err){
    console.log(err)
    res.redirect('http://localhost:3000/login')
    }
})

So as I described in my code , I am stuck here with my token , and I want to send it to client side, and there store my token to localStorage.

some advices?

1 Answers

It is not best practice to store tokens in local storage, as it is not secure. If you have a backend API, it's best to use OAuth 2.0 Authorization code flow to ensure the security of the access token.

This would entail using the OAuth server (github) to get an authorization code through the Log in page. The code is then passed to your API and exchanged on the more trusted "back channel" (between your API and OAuth server) for the actual access token used for authentication. The OAuth server will know who you are because you would use your ClientId and ClientSecret to query the token (Storing ClientId and ClientSecret in javascript is also unsecure)

This means the token will be stored on your server, and you will need to provide endpoints on your API to fetch the required data.

Here is a video which explains this quite nicely.

Related