Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Omniauth Support? #2

Open
g33kidd opened this issue May 11, 2017 · 4 comments
Open

Omniauth Support? #2

g33kidd opened this issue May 11, 2017 · 4 comments

Comments

@g33kidd
Copy link

g33kidd commented May 11, 2017

Does this support Omniauth at the moment? Or is this planned?

@timscott
Copy link
Owner

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.

@azeemh
Copy link

azeemh commented Oct 18, 2017

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.

@timscott
Copy link
Owner

@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.

@timscott
Copy link
Owner

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
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants