Open g33kidd opened 7 years ago
It's planned. I've got some code in a side project that does oauth with Rails and jwt (not Devise or Omniauth) which I can use as a starting point. That said, the app I'm currently working on does not require social logins, so I'm not sure how soon I will get to it.
Hi Tim, love what you're doing here, need a way to use app that supports OmniAuth login and reactjs... If there's anyway we can help get that moving or even contribute to the cause please lmk.
@azeemh - I've been planning to work on this. Help is certainly welcomed.
I have an side project where I'm doing OAuth with react and devise. I created that before this project. If I get a chance, I will create an oauth branch this weekend with some of that code as a starting point. From there you can fork it and help out maybe.
If it's urgent, and you want to start from scratch, go ahead and fork master now.
I created a branch: https://github.com/timscott/react-devise/tree/auth-provider-support. Basically it adds an action providerLogin
which you will call from your view with a provider name and provider auth token.
I did not create a view, and I'm not sure I want to. There are probably many ways to create oauth buttons in react. There are various libraries that provide the basic building blocks, or you can roll your own. I'm not sure I want to take more dependencies and/or more opinions.
For reference, here is some code I pulled from another side project and which I started to integrate it into react-devise-sample. I started, but gave up for now. I was having some trouble with getting the token back from the server, and also, for this to work I would need to create Facebook and Google apps, which I don't want to trouble with now.
That said, this code might help as a starting point to create your own view. I'm also open to considering a default provider auth view for react-devise
:
import React from 'react';
import FacebookLogin from 'react-facebook-login';
import GoogleLogin from 'react-google-login';
import {providerLogin} from 'react-devise/lib/actions';
import styled from 'styled-components';
import FontAwesome from 'react-fontawesome';
import {connect} from 'react-redux';
import {Flex, Box} from 'grid-styled';
import {Redirect} from 'react-router-dom';
const LoginContainer = styled(Flex)`
margin-top: 100px;
`;
const LoginButtonContainer = styled.div`
margin-bottom: 5px;
`;
const buttonStyles = `
font-family: Helvetica, sans-serif;
font-weight: 700;
font-smoothing: antialiased;
color: #fff;
cursor: pointer;
display: inline-block;
font-size: calc(.27548vw + 12.71074px);
text-decoration: none;
text-transform: uppercase;
transition: background-color .3s, border-color .3s;
padding: calc(.34435vw + 3.38843px) calc(.34435vw + 8.38843px);
width: 250px;
`;
const MyFacebookLogin = ({className, ...props}) => {
return (
<FacebookLogin cssClass={className} {...props} />
);
};
const StyledFacebookLogin = styled(MyFacebookLogin)`
${buttonStyles}
background-color: #4c69ba;
border: calc(.06887vw + .67769px) solid #4c69ba;
`;
const StyledGoogleLogin = styled(GoogleLogin)`
${buttonStyles}
background-color: #d1484d;
border: calc(.06887vw + .67769px) solid #d1484d;
`;
const SocialIcon = styled(FontAwesome)`
margin-right: 10px;
font-size: 1.3em;
`;
const Alert = styled(Box)`
background-color: #f3c4c9;
margin-bottom: 10px;
color: #aa2833;
font-weight: bold;
border: 1px solid #aa2833;
border-radius: 3px;
padding: 3px 10px;
`;
const mapStateToProps = state => {
return {
currentUser: state.currentUser
};
};
const mapDispatchToProps = dispatch => {
return {
providerLogin: data => {
return providerLogin(data, dispatch);
}
};
};
const withProviderAuth = (provider, Button) => {
const ProviderAuth = ({providerLogin}) => {
const login = accessToken => {
return providerLogin({
provider,
accessToken
});
};
const authenticate = response => {
return login(response.accessToken);
};
const authenticateFailed = response => {
console.log(`Authentication failed with ${provider}. ${response}`);
};
return <Button
authenticate={authenticate}
authenticateFailed={authenticateFailed}
/>;
};
return connect(mapStateToProps, mapDispatchToProps)(ProviderAuth);
};
const OauthFacebook = withProviderAuth('facebook', ({authenticate}) => {
return (
<StyledFacebookLogin
appId={process.env.REACT_APP_FACEBOOK_APP_ID}
fields=""
callback={authenticate}
icon={<SocialIcon name="facebook" />}
/>
);
});
const OauthGoogle = withProviderAuth('google', ({authenticate, authenticateFailed}) => {
return (
<StyledGoogleLogin
clientId={process.env.REACT_APP_GOOGLE_APP_ID}
onSuccess={authenticate}
onFailure={authenticateFailed}
>
<SocialIcon name="google" />
<span>Login with Google</span>
</StyledGoogleLogin>
);
});
let OauthView = ({currentUser, location: {state: {flash, from: {pathname: returnTo} = {}} = {}} = {}}) => {
if (currentUser) {
if (currentUser.isLoggedIn) {
return <Redirect to={returnTo || '/'} />;
}
if (currentUser.isLoggingIn) {
return (
<div>Logging in...</div>
);
}
}
return (
<LoginContainer align="center" column>
{flash && <Alert>{flash}</Alert>}
<Box>
<LoginButtonContainer>
<OauthFacebook />
</LoginButtonContainer>
<LoginButtonContainer>
<OauthGoogle />
</LoginButtonContainer>
</Box>
</LoginContainer>
);
};
OauthView = connect(mapStateToProps, mapDispatchToProps)(OauthView);
export {
OauthView,
OauthFacebook,
OauthGoogle
};
Does this support Omniauth at the moment? Or is this planned?