Reputation: 1329
I'm adding OAuth into my github clientside application. I have the final auth token being returned successfully, but I feel like I hacked my workflow.
1) User clicks href
link from component to hit the initial OAUTH route
2) Retrieve token from Github for user identity
3) Github redirects to my server route and my server route sends an additional POST
to the /access_token
request page with the client_secret
, id
and code
from the above step.
4) Finally I redirect from the above route back to my UI and set a URL parameter in the process
5) In the componentDidMount
I strip the final auth token from the window.url
and set it in my state
Note: I plan on storing the token in Redux later, but this is the base level as to what I'm doing.
app.get("/login", async (req, res) => {
// Get the identity token from GitHub origin
return await axios
.post("https://github.com/login/oauth/access_token", {
code: req.query.code,
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET
})
.then(async resp => {
// Little hack to parse out the query params into an object
let data = await url.parse("http://parse.com?" + resp.data, {
parseQueryString: true
}).query;
res.redirect(
url.format({
pathname: Environment.getUrl(),
query: {
token: data.access_token
}
})
);
});
});
export default class GithubAuthentication extends React.Component {
state = {
authToken: "DATA"
};
componentDidMount() {
let currUrl = window.location.href;
this.setState({ authToken: currUrl.split("token=")[1] });
}
render() {
return (
<React.Fragment>
<a href="https://github.com/login/oauth/authorize?client_id=b5cd37110eb31620aad7">
{this.state.authToken ? "Logout" : "Login With Github"}
</a>
<span>{this.state.authToken}</span>
</React.Fragment>
);
}
}
1) The one thing I wasn't able to figure out was to make the href
link a controlled component and actually hit the auth URL with something like SuperAgent
or Axios
. Instead, I'm forced to use this href
link, not sure why.
2) Is this actually a sensible flow for getting the final auth token?
Upvotes: 2
Views: 1632
Reputation: 2814
Regarding question 2, from a security standpoint, it is better to keep access token on server-side and never send the token to client-side.
I couldn't find good written resources, so I'd like to share this video which sums up how to deal with access token clearly.
https://www.youtube.com/watch?v=CHzERullHe8&list=PL78z2Z3ZApYcKb-GDQt6ikdN2EDqmKJrT&index=12&t=419s
Take away from the video
To actually implement this flow, you can use cookie-session to generate session. You can also use github-passport to simplify the implementation.
https://github.com/expressjs/cookie-session https://github.com/jaredhanson/passport-github
Upvotes: 1
Reputation: 145
1) I think you should reorganize your app so that you can use a component instead of an href link. You would know whether you're authenticated or not based on the value on the state property. This value can be passed as prop to your component which is where you would put the logic of authenticated ? "Logout" : "Login" or anything else.
2) the flow is OK but you have to make sure you do server side validation of the token since it's easy to just flip the switch on the UI and the pretend you're authenticated very easily.
Upvotes: 0