Express.js, le Play!>Framework du Javascript ? La suite âŠ
Hier, câĂ©tait : cf. 1Ăšre partie âExpress is Play (?)â
Aujourdâhui, ce sera lâauthentification twitter, mais tout dâabord un peu de cosmĂ©tique.
⊠Faites vous un cafĂ© avant, il faut ĂȘtre concentrĂ© ;)
Codemirror
Etant donnĂ© que nous saisissons du markdown, allons jusquâau bout et proposons un Ă©diteur de code avec un peu de couleur. Pour cela nous allons utiliser CodeMirror, un Ă©diteur de code en js assez sympa Ă utiliser (et surtout facile Ă utiliser) : http://codemirror.net/
Installation
Il faut récupérer ici : https://github.com/marijnh/CodeMirror2
codemirror.js
, que vous aller copier danspublic/javascripts
- le mode markdown de codemirror :
markdown.js
, que vous aller copier danspublic/javascripts
- ainsi que
xml.js
(encore danspublic/javascripts
)
puis dans public/stylesheets
:
codemirror.css
rubyblue.css
(le thĂšme)
Utilisation
Dans /views/layout.ejs
, ajouter les références aux feuilles de style :
<html>
<head>
<title>styKKeKode</title>
<link rel="stylesheet" href="stylesheets/bootstrap.css">
<link rel="stylesheet" href="stylesheets/bootstrap-responsive.css">
<link rel="stylesheet" href="stylesheets/default.min.css">
<link rel="stylesheet" href="stylesheets/codemirror.css">
<link rel="stylesheet" href="stylesheets/rubyblue.css">
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
</style>
<style type="text/css">
.CodeMirror {border-top: 1px solid gray; border-bottom: 1px solid gray;}
pre { color:white; }
</style>
</head>
<%- body %>
</html>
Remarque : jâai modifiĂ©(surcharchĂ©) .CodeMirror
(vous nâĂȘtes pas obligĂ©) et changĂ© lâattribut color
de pre
(il y avait un âconflit de couleursâ avec bootstrap)
On retourne dans /views/index.ejs
,
# HTML :
Dans notre formulaire html, il nây a pas grand chose qui change, nous allons juste ajouter un âcompteurâ pour le nombre de caractĂšres Ă saisir :
<!-- mon formulaire de saisie -->
<div id="snippet-form">
<h2>Go ...</h2>
<form action="/" class="well">
<label>Title : </label>
<input id="title" type="text" class="span3" style="width:100%" placeholder="title"/>
<label>Code Snippet : (with markdown) </label>
<textarea id="code" placeholder="code" style="width:100%" rows="5"></textarea>
<!-- on ajoute un compteur -->
<b><div id="counter">0/1455</div></b>
<!-- -->
<label>User : </label>
<input id="user" type="text" placeholder="user"/>
<button id="postsnippet" type="submit" class="btn">Ajouter un Snippet</button>
<!--<input type="submit" value="Ajouter un Snippet" />-->
</form>
</div>
# Javascript :
LĂ on on a un peu plus de boulot :
PremiÚrement, pensez à ajouter les références au librairies codemirror :
<script src="javascripts/codemirror.js"></script>
<script src="javascripts/xml.js"></script>
<script src="javascripts/markdown.js"></script>
Ensuite, on ajoute le code nécessaire :
Juste aprĂšs $(document).ready(function() {
ajouter ceci :
//le compteur
var counter = $("# counter");
//une référence à notre bouton d'ajout
var postSnippetButton = $("# postsnippet");
counter.css("color","green");
//on transforme notre textarea en super Ă©diteur de code
window.editor = CodeMirror.fromTextArea(document.getElementById("code"), {
mode: 'markdown',
lineNumbers: true,
matchBrackets: true,
indentUnit : 4,
theme: "rubyblue",
lineWrapping : true,
//on vérifie que l'on ne saisi pas plus de 1455 caractÚre
//il faudra quand mĂȘme vĂ©rifier aussi cĂŽtĂ© serveur
onChange : function() {
counter.html(editor.getValue().length + "/1455");
if(editor.getValue().length > 1455) {
counter.css("color","red");
postSnippetButton.hide();
} else {
postSnippetButton.show();
counter.css("color","green");
}
}
});
editor.getScrollerElement().style.height = "170px";
editor.getGutterElement().style.height = "170px";
Une derniĂšre petite modification : dans notre vue window.SnippetFormView
, nous allons modifier le code qui permet de récupérer la saisie faites dans la textarea, puis de vider celle-ci. Remplacez donc :
code : converter.makeHtml(this.$('# code').val())
parcode : converter.makeHtml(editor.getValue())
- et
this.$('textarea').val('')
pareditor.setValue('')
Et voilà pour la partie cosmétique, si tout va bien vous devriez obtenir ceci :
Authentification Twitter
Pour cette partie, je dois reconnaĂźtre que cela mâa pris un peu plus de temps. Alors je ne fais pas le tour complet de lâauthentification via Twitter, mais ça devrait vous donner assez de billes pour creuser plus loin. Lâobjectif de cette partie est le suivant :
- pouvoir sâauthentifier via Twitter
- ne pouvoir poster quâune fois autentifiĂ©
Pré-requis
Nous nâallons pas rĂ©-inventer la roue (je ne suis mĂȘme pas sĂ»r dây arriver), pour gĂ©rer les sessions et sâauthentifier avec un compte de rseau social, il existe lâexcellente librairie everyauth : https://github.com/bnoguchi/everyauth. Je nâai rien fait de gĂ©nial, je me suis juste inspirrĂ© des codes dâexemples https://github.com/bnoguchi/everyauth/blob/master/example/server.js (jâai juste customisĂ© Ă ma sauce).
- aller dans le répertoire de votre application :
cd stykkekode
- tapez la commande
npm install everyauth
# Aller enregistrer son application chez Twitter
- aller sur le site des développeurs : https://dev.twitter.com/
- âsignerâ vous
- sĂ©lectionnez âCreate an Appâ : https://dev.twitter.com/apps/new
Voici comment jâai rempli les informations :
- Name :
stykkekode_dev
- Description :
tutorial about authentication with express.js
- Website :
http://dev.k33g.org
(pour le moment vous nâavez pas Ă mettre un vĂ©ritable nom de domaine) - Callback URL :
http://dev.k33g.org:3000/auth/twitter/callback
(il est important de garder le mĂȘme nom de domaine) - Acceptez les conditions dâutilisation
- Clickez sur âCreate your twitter applicationâ
- Votre application vient dâĂȘtre crĂ©Ă©e
- Notez quelque part dans un fichier votre Consumer key et votre Consumer secret
Ensuite :
- Clickez sur âCreate my access tokenâ
# ParamĂ©trer son poste : âfake http://dev.k33g.orgâ
En mode commande, tapez : sudo pico /etc/hosts
et ajoutez la ligne suivante :
127.0.0.1 dev.k33g.org
Et sauvegardez, puis quittez.
Donc Ă partir de maintenant, si vous lancez votre application : nodemon server.js
et que vous tapez lâurl http://dev.k33g.org:3000/ vous serez dirigĂ©s sur votre application locale.
Et donc cela va vous permettre de tester le callback de twitter en local
⊠ça câest fait.
Retournons maintenant dans le code.
Déclaration et paramétrage de everyauth
Nous allons tout dâabord crĂ©er un fichier config.js
Ă la racine de lâapplication. Et nous allons renseigner dans ce fichier les informations nĂ©cessaires Ă la connexion avex Twitter :
module.exports = {
twit: {
consumerKey: 'ICI VOTRE CONSUMER KEY'
, consumerSecret: 'ICI VOTRE CONSUMER SECRET'
}
};
Ensuite allons dans server.js
:
Ajoutons les références à everyauth et config.js :
var express = require('express')
, routes = require('./routes')
, everyauth = require('everyauth') /* AUTHENTICATION */
, conf = require('./config'); /* AUTHENTICATION */
everyauth.debug = true;
Dans la partie âConfigurationâ, modifier de la maniĂšre suivante : (on utilise le mĂ©canisme de gestion de session dâeveryauth)
app.configure(function(){
/* === start of authentication === */
app.use(express.cookieParser());
app.use(express.session({
secret:'bobmorane',
"store": new express.session.MemoryStore({ reapInterval: 60000 * 10 })
}));
app.use(everyauth.middleware());
/* === end of authentication === */
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
En fin de fichier juste avant app.listen(3000);
ajouter everyauth.helpExpress(app);
everyauth.helpExpress(app);
app.listen(3000);
Utilisation dâeveryauth
# ModĂšle âuserâ
PremiĂšrement, allez crĂ©er un âmodelâ user.js
dans le répertoire models
avec le code suivant
/* USER MODEL */
var user = function(id, source, sourceUser) {
console.log("New User : ", id, source);
this.id;
this.source = source;
this.sourceUser = sourceUser;
}
//static members
user.listById = {};
user.twitterListById = {};
/*
user.list : tous les users quel que soit le mode d'authentification
user.twitterList : les users authentifiés via twitter
everyauth permet de nombreux modes d'authentification (google par exemple)
cela permettra d'ajouter d'autres modes si on le souhaite
*/
user.nextUserId = 0;
//static methods
user.add = function(source, sourceUser) {
user.nextUserId+=1;
var authenticatedUser = new user(user.nextUserId, source, sourceUser);
console.log("### # # ### # # ### # # ### # # ### # # ### # # ### ");
console.log(authenticatedUser);
console.log("### # # ### # # ### # # ### # # ### # # ### # # ### ");
user.listById[authenticatedUser.id] = authenticatedUser;
return authenticatedUser;
};
user.findById = function(id) {
return user.listById[id];
};
user.findByTwitterId = function(id) {
return user.twitterListById[id];
};
exports.user = user;
# Utilisation dans server.js
Entre var app = module.exports = express.createServer();
et app.configure(...)
ajoutez :
/* === start of authentication === */
var user = require('./models/user').user;
//toujours surcharger ceci :
everyauth.everymodule
.findUserById( function (id, callback) {
callback(null, user.findById(id));
});
//s'authentifier chez twitter
everyauth
.twitter
.consumerKey(conf.twit.consumerKey)
.consumerSecret(conf.twit.consumerSecret)
.findOrCreateUser( function (sess, accessToken, accessSecret, twitUser) {
var tmp = user.findByTwitterId(twitUser.id);
if(tmp) {
// ne rien faire
} else {
tmp = user.add('twitter', twitUser);
user.twitterListById[twitUser.id] = tmp;
}
return tmp;
})
.redirectPath('/'); //une fois authentifié rediriger vers "/"
/* === end of authentication === */
# Utilisation dans la vue index.ejs
Ajoutons un peu de code Ă notre vue juste aprĂšs <div class="container">
:
Donc si vous nâĂȘtes pas authentifiĂ© dans twitter, cela vous affichera un lien pour aller vous connecter. Une fois authentifiĂ© cela affichera les infos twitter de votre compte. On teste :
- relancez votre application :
nodemon server.js
- si vous ĂȘtes connectĂ© Ă twitter dans votre navigateur, dĂ©connectez vous (câest mieux pour le test)
Vous devriez obtenir ceci :
Authentifiez vous :
Vous ĂȘtes redirigĂ© vers votre application :
Câest cool ça fonctionne (en tous cas chez moi, câest ok) mais ce nâest pas beau.
Derniers réglages
Toujours dans index.ejs
on modifie le code précédent :
Puis, vous modifiez le code html pour ne permettre de poster quâune fois authentifiĂ© (le bouton nâapparaĂźt que si vous ĂȘtes authentifiĂ©) :
Et pensez Ă dĂ©activer le âvidageâ des zones de texte (on veut conserver le pseudo utilisateur) :
//this.$('input[type="text"]').val('');
et remplacez par :
this.$('# title').val('');
(oui, je sais, les id cémal)
Et enfin, vous pouvez testez : juste raffraßchir la page, ça devrait suffire : Tada !!!
VoilĂ , vous avez de quoi vous amuser. Vous pouvez tester lâapplication en vrai ici : http://stykkekode.cloudno.de/.
Et pour la prochaine fois, nous verrons comment utiliser CouchDB pour sauvegarder et retrouver les messages.
Bon dimanche Ă tous.
Tweet