1. Setup a Symfony Flex project
- Symfony Flex project: Setup a Symfony Flex
- Install Symfony server:
$ composer require symfony/web-server-bundle --dev
- Run the app:
$ php bin/console server:run
- Note: If you use apache: Configuring a Web Server
2. Setup Spotify app
- Create a spotify app at Spotify Developer Dashboard
- Remember to put the
Redirects URI
into a App Settings:http://127.0.0.1:8000/login/oauth
and your finally url. - Get a Client ID, and Client Secret.
3. Requirements
- We use the jwilsson/spotify-web-api-php PHP class wrapper for Spotify's Web API.
$ composer require jwilsson/spotify-web-api-php
4. Templating
- We build a
templates/base.twig.html
with a Semantic UI. - and we create a
templates/auth/
folder for the templates.
# templates/base.twig.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.1/dist/semantic.min.css">
{% block stylesheets %}{% endblock %}
</head>
<body>
{% block body %}
{% block header %}
<header>
</header>
{% endblock %}
<main>
{% block content %}
{% endblock %}
</main>
{% endblock %}
{% block footer %}
<footer>
</footer>
{% endblock %}
<script src="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.1/dist/semantic.min.js"></script>
{% block javascripts %}{% endblock %}
</body>
</html>
5. Controller (and templates)
- We create a
AuthController
with these actions:
5.1. Constructor
- We configurate and we declare the spotify api
// src/Controller/AuthController
private $spotifyParams;
private $spotify;
public function __construct()
{
$this->spotifyParams = [
'client_id' => 'e4e6d0a8791448eebxxxxxxxxxxxxx',
'client_secret' => '14b342672e7447axxxxxxxxxxxxx',
'scope' => ['user-read-email','user-read-private','playlist-read-private',
'playlist-read-collaborative','playlist-modify-public',
'playlist-modify-private','user-follow-read','user-follow-modify']
];
$this->spotify = new SpotifyWebAPI\Session(
$this->spotifyParams['client_id'],
$this->spotifyParams['client_secret'],
'http://127.0.0.1:8000/login/oauth'
);
}
5.2. Login
- We get the user authorize url.
// src/Controller/AuthController
/**
* @Route("/login", name="login")
*/
public function login( SessionInterface $session )
{
$options = [
'scope' => $this->spotifyParams['scope']
];
$spotify_auth_url = $this->spotify->getAuthorizeUrl($options);
return $this->render('auth/login.html.twig', array(
'spotify_auth_url' => $spotify_auth_url
));
}
- Template:
# templates/auth/login.twig.html
{% extends "base.html.twig" %}
{% block body %}
<style type="text/css">
body { background-color: #DADADA; }
body > .grid { height: 100%; }
.column { max-width: 450px; }
</style>
<div class="ui middle aligned center aligned grid">
<div class="column">
<h2 class="ui teal image header">
<div class="content">
Log-in to your account
</div>
</h2>
<form class="ui large form">
<div class="ui stacked segment">
<a href="{{ spotify_auth_url }}" class="ui fluid large teal submit button"><i class="spotify icon"></i> Login by Spotify</a>
</div>
{% for flashMessage in app.session.flashbag.get('error') %}
<div class="ui error message">{{ flashMessage }}</div>
{% endfor %}
{% for flashMessage in app.session.flashbag.get('success') %}
<div class="ui error message">{{ flashMessage }}</div>
{% endfor %}
</form>
</div>
</div>
{% endblock %}
- Capture:
5.3. OAuth
- The user enter at this action after accept our spotify application.
- We save the session and we redirect to the user profile
- Note: Remember to assign this url into your spotify app settings. In my case
http://127.0.0.1:8000/login/oauth
// src/Controller/AuthController
/**
* @Route("/login/oauth", name="oauth")
*/
public function oauth(Request $request, SessionInterface $session)
{
$accessCode = $request->get('code');
$session->set('accessCode', $accessCode); // symfony session
$this->spotify->requestAccessToken($accessCode);
$accessToken = $this->spotify->getAccessToken();
$session->set('accessToken', $accessToken); // symfony session
return $this->redirectToRoute('profile');
}
5.4. Profile
- Use the profile action to retrieve the user information and show it.
// src/Controller/AuthController
/**
* @Route("/profile", name="profile")
*/
public function profile(Request $request, SessionInterface $session )
{
$accessToken = $session->get('accessToken');
if( ! $accessToken ) {
$session->getFlashBag()->add('error', 'Invalid authorization');
$this->redirectToRoute('login');
}
$api = new SpotifyWebAPI\SpotifyWebAPI();
$api->setAccessToken($accessToken);
$me = $api->me();
return $this->render('auth/profile.html.twig', array(
'me' => $me
));
}
- Template
# templates/auth/profile.html.twig
{% extends "base.html.twig" %}
{% block content %}
<div class="ui container">
<h1>Profile</h1>
<div class="ui cards">
<div class="ui raised card">
<div class="content">
<div class="header">{{ me.display_name }}</div>
<div class="meta">
<span class="right floated time">
<a href="{{ me.external_urls.spotify }}" target="_blank"><i class="linkify icon"></i></a>
</span>
<span class="category">{{ me.id }}</span>
</div>
<div class="description">
{{ me.product }}
</div>
</div>
<div class="extra content">
<i class="check icon"></i>
{{ me.followers.total }} Followers
</div>
</div>
</div>
<a href="{{ path('logout') }}" class="ui red button right floated"><i class="power icon"></i> Logout</a>
<pre><code>
{{ dump(me) }}
</code></pre>
</div>
{% endblock %}
- Capture:
5.5. Logout
- We clean the session and redirect to login with the flash message.
// src/Controller/AuthController
/**
* @Route("/logout", name="logout")
*/
public function logout( SessionInterface $session )
{
$session->clear();
$session->getFlashBag()->add('success', 'You have successfully logged out');
return $this->redirectToRoute('login');
}
6. Entire Controller
// src/Controller/AuthController.php
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use SpotifyWebAPI;
class AuthController extends AbstractController
{
private $spotifyParams;
private $spotify;
public function __construct()
{
$this->spotifyParams = [
'client_id' => 'e4e6d0a8791448eebb643e4ec22d0e89',
'client_secret' => '14b342672e7447a19b03f03c79a11bb8',
'scope' => ['user-read-email','user-read-private','playlist-read-private',
'playlist-read-collaborative','playlist-modify-public',
'playlist-modify-private','user-follow-read','user-follow-modify']
];
$this->spotify = new SpotifyWebAPI\Session(
$this->spotifyParams['client_id'],
$this->spotifyParams['client_secret'],
'http://127.0.0.1:8000/login/oauth'
);
}
/**
* @Route("/login", name="login")
*/
public function login( SessionInterface $session )
{
$options = [
'scope' => $this->spotifyParams['scope']
];
$spotify_auth_url = $this->spotify->getAuthorizeUrl($options);
return $this->render('auth/login.html.twig', array(
'spotify_auth_url' => $spotify_auth_url
));
}
/**
* @Route("/login/oauth", name="oauth")
*/
public function oauth(Request $request, SessionInterface $session)
{
$accessCode = $request->get('code');
$session->set('accessCode', $accessCode); // symfony session
$this->spotify->requestAccessToken($accessCode);
$accessToken = $this->spotify->getAccessToken();
$session->set('accessToken', $accessToken); // symfony session
return $this->redirectToRoute('profile');
}
/**
* @Route("/profile", name="profile")
*/
public function profile(Request $request, SessionInterface $session )
{
$accessToken = $session->get('accessToken');
if( ! $accessToken ) {
$session->getFlashBag()->add('error', 'Invalid authorization');
$this->redirectToRoute('login');
}
$api = new SpotifyWebAPI\SpotifyWebAPI();
$api->setAccessToken($accessToken);
$me = $api->me();
return $this->render('auth/profile.html.twig', array(
'me' => $me
));
}
/**
* @Route("/logout", name="logout")
*/
public function logout( SessionInterface $session )
{
$session->clear();
$session->getFlashBag()->add('success', 'You have successfully logged out');
return $this->redirectToRoute('login');
}
}
?>
7. Thanks to
EOF