knpuniversity / oauth2-client-bundle

Easily talk to an OAuth2 server for social functionality in Symfony
https://symfonycasts.com
MIT License
787 stars 146 forks source link

Demo app: login with github #437

Open tacman opened 9 months ago

tacman commented 9 months ago

Since everyone downloading this bundle uses Symfony and Github, what do you think of creating a simple demo that allows users to login with github and display some profile information.

We could use that as a basis for updating the documentation, e.g. #427 .

I'm happy to kick it off, I'll start with a fresh project and document my steps. The demo should work with Symfony 6.4 or Symfony 7 (latest release and latest LTS).

Then we can add Google and Facebook, but Github is by far the easiest to integrate, because they allow redirect urls like my-app.wip, where Google doesn't.

bocharsky-bw commented 9 months ago

It's an interesting idea. The question is where to host it. I would say a free Heroku plan would be ideal for this, though it's not an option anymore. Or do you mean a demo app that users will only download locally? And yeah, GitHub probably would be the best for this example. Anyway, it will put an additional load on maintainers to maintain it, because a bad not working demo is worse than no demo IMO. I wonder about other opinions here

tacman commented 9 months ago

I used to love heroku for exactly that! I now have a dokku server that I use for these kind of projects. Normally I'd be happy with just a locally working version of an application, but because of the trickiness of the redirect urls, we have to have it working on a production server as well.

I agree, a demo that doesn't work is pretty embarrassing. But if we can't make a trivial demo work, something is wrong with either the code or the documentation.

dokku is pretty cool, I host it on hetzner for some amazingly cheap price.

tacman commented 9 months ago

Again, I'm happy to kick it off, in part because I have it working locally on a project but not on the production server, and I don't know why. I thought it was related to the #436 issue, and it's definitely getting further now, but I still get the error

 Error fetching OAuth credentials: "redirect_uri_mismatch".
weaverryan commented 9 months ago

I'd welcome someone like you @tacman creating a nice demo - we could even link to it. But I don't think we should deploy it... it just gets tricky because naturally, some service will change something and it will break. I don't have the space to be responsible for debugging that some day in the future :)

tacman commented 9 months ago

One thing I like even better than a demo app is step by step instructions from a new Symfony app. So I've created that at https://github.com/survos-sites/oauth-demo

If you have postgres and the symfony client installed, you can get to a functional register / login / logout application by running this bash script.

symfony new --webapp oauth-demo && cd oauth-demo
# change
echo "DATABASE_URL=postgresql://postgres:docker@127.0.0.1:5434/auth-demo?serverVersion=16&charset=utf8" > .env.local

bin/console doctrine:database:create
composer config extra.symfony.allow-contrib true
composer require knpuniversity/oauth2-client-bundle league/oauth2-github
bin/console importmap:require bootstrap
echo "import 'bootstrap/dist/css/bootstrap.min.css'" >> assets/app.js

symfony console make:controller AppController
sed -i "s|/app|/|" src/Controller/AppController.php 

bin/console make:user --is-entity --identity-property-name=email --with-password User -n

echo "github_id,string,80,yes," | sed "s/,/\n/g"  | bin/console make:entity User
echo "yes,no,yes,14" | sed "s/,/\n/g"  | bin/console make:registration

bin/console make:migration
bin/console doctrine:migration:migrate -n

echo "1,AppAuthenticator,,," | sed "s/,/\n/g"  | bin/console make:auth
sed  -i "s|some_route|app_app|" src/Security/AppAuthenticator.php
sed  -i "s|// return new|return new|" src/Security/AppAuthenticator.php
sed  -i "s|throw new|//throw new|" src/Security/AppAuthenticator.php

echo '' > templates/social_media_login.html.twig
cat <<'EOF' > templates/app/index.html.twig
{% extends 'base.html.twig' %}
{% block body %}
    <div>
        <a href="{{ path('app_app') }}">Home</a>
    </div>
    {% if is_granted('IS_AUTHENTICATED_FULLY') %}
        <a class="btn btn-primary" href="{{ path('app_logout') }}">Logout {{ app.user.email }} </a>
    {% else %}
        <a class="btn btn-primary" href="{{ path('app_register') }}">Register</a>
        <a class="btn btn-secondary" href="{{ path('app_login') }}">Login</a>
    {% endif %}
    {{ include('social_media_login.html.twig') }}
{% endblock %}
EOF

symfony proxy:domain:attach oauth-demo
symfony server:start -d
symfony open:local --path=/register

The rest of the README continues with a github integration. The worse part is creating the application on github itself, but that's documented.

I'd love some feedback, and then I'll update the README to reflect the controller and such.

I will add more to this demo to make it feel more like a real app, but with these instructions anyone should be able to add github login to a new Symfony site.

tacman commented 9 months ago

I have a demo running at https://oauth-demo.survos.com/, but it fails after login because the redirect url is http, not https.

I can't figure out what I'm doing wrong, it's such a basic demo. It works fine locally, using ngrok for the google login (as long as TRUSTED_HOSTS is set and configure).

But no matter what I do, the redirect URL generated by the AbstractProvider returns http, not https.

https://github.com/survos-sites/oauth-demo/

Once this works I'll use it to update the documentation here, but I've been looking at this for days and can't figure out a solution, my hack at #438 is problematic but perhaps on the right track.

I'm pleading for help by some experts here. I can make up a video if that helps.

Obviously, if forking or running the demo, you'd need to set all your own client id and keys, which makes this a bit of a pain -- twice, once for local and once for production, and then set the keys up on production, then deploy to production.

I've been deploying to dokku, I wish heroku free apps were still available.