Gestion de l’authentification de vos sites avec RPX

rpx_2

Étant en plein développement d’un petit pastebin-like en python ( enfin c’est un peu plus que ca, mais j’en reparlerais quand il sera fini ), le problème de la gestion de mes utilisateurs s’est posé assez vite.

Ne voulant pas avoir à gérer moi même l’authentification ( D’abord parce que je ne juge pas ça nécessaire, des choses comme OpenID le faisant très bien, et ensuite, ok, par flemme un peu, pas envie de gerer les mots de passes, les resets, d’être sur que tout est 100% secure…),  je me suis rappelé que mon compte StackOverflow s’identifie via mon google account. En creusant un peu, j’ai appris que leur authentification était gérer par un service se nommant RPX.

Mais RPX c’est quoi exactement ?

RPX est un service d’authenfication par OpenID assez jeune, et pourtant utilisé sur un certain nombre de sites de taille importante, comme UserVoice , Interscope, ou encore StackOverflow, dont je parlais dans un précédent billet.

Allez, comme un joli schéma vaut mieux qu’un long discours, RPX fournis un service qui ressemble à ca :

rpx_howto

Traduction : RPX se positionne entre votre site web et les fournisseurs d’identification tierces (comme OpenID ou GoogleID par exemple ), et facilite l’utilisation de ces derniers.

En pratique, lorsque l’utilisateur va vouloir s’authentifier sur votre site, il va passer par une widget RPX (iframe embarquée ou popup), qui lui présente la liste des fournisseurs disponibles.

Par exemple, sur le site d’uservoice (la widget est a gauche, uservoice propose aussi une inscription directe au site) :

login_uservoice

L’utilisateur choisir son système d’authentification et est alors dirigé vers la page de login du fournisseur tier. Par exemple pour facebook, il arrive ici :

auth_facebook

Une fois l’authentification effectuée, l’utilisateur est redirigé vers votre site. (Pour certain fournisseurs comme google, lors de la première identification, l’utilisateur passe par une page lui demandant de confirmer qu’il autorise bien le site à accéder à ses informations)

auth_google

Et c’est la que RPX fait la jointure retour avec votre site : une fois que l’utilisateur s’est authentifié, RPX vous indique (de façon sécurisée évidemment) si l’utilisateur s’est correctement authentifié ou non, et si oui, il vous transmet ses informations publiques ( email, nom d’utilisateur, nom d’usage et clef openId ).

A partir de la, vous avez votre utilisateur authentifié, vous savez qui il est, et vous êtes libre de faire ce que vous voulez (inscription en base, passage en session…)

Coté services

RPX propose 3 types de comptes :

  • Basic ( Gratuit )
  • Plus ( 100$ / an )
  • Pro ( 500$ / an )

Je vous rassure tout de suite, le basic est largement suffisant pour tout ce qu’on pourrait vouloir sur un site de petite voir moyenne envergure :

Il est limité à 6 providers d’identifications (alors que les autres types de comptes n’ont pas de limite), cependant on peut quand même choisir ceux qu’on veut tous ceux disponibles,  c’est amplement suffisant ( personnellement j’ai pris OpenID, Google, Facebook, Twitter, Yahoo et AOL, ce qui couvre deja pas mal). A noter que pour facebook et twitter, il faut faire une petite manip pour créer une application tierse, mais tout est très bien expliqué sur le site de RPX, ca se passe donc sans problèmes.

Hormis le nombre de providers, les différences entre les types de comptes viennent surtout du support apporté à coté ( profiling, stats, customisation de la widget… ). plus d’information dans le comparatif sur le site officiel.

Les points négatifs

Même si le service proposé est vraiment intéressant, il faut quand même noter quelques points négatifs :

Tout d’abord, l’appel à la widget affichant le service d’identification est relativement lent (au moins pour les comptes gratuits, ca à l’air moins lent sur uservoice et stackoverflow). En effet l’affichage de l’iframe sur la page de login doit mettre une bonne seconde à s’afficher. C’est un détail, mais tout de même.

Ensuite, cela peut dérouter les utilisateurs ne connaissant pas le principe :l’utilisateur arrive sur un site, cherche à s’inscrire, et se retrouve diriger vers sa page google ou facebook. Cela peut dérouter quelques peu, voir même ressembler à du phishing. De plus, même si, quand on prend le temps de se renseigner, on sais que les informations fournis par les providers sont publiques (email, nom, clef openId … rien de très compromettant), on peut être effrayer au début en autorisant facebook à délivrer ses informations personnels à un site tier…

Enfin, pour finir, même si les risques sont très faibles, le jour ou le service RPX tombe en rade, on se retrouve avec un joli site sur lequel toute identification est impossible…

Un retour un peu plus complet sur les “dangers” de RPX est consultable ici , même si la plupart des choses ne sont pas spécifiquement objectives.

Sinon, pour ceux que ca intéresse, un autre billet devrait bientôt suivre sur comment brancher RPX sur un Pylons. En attendant, le tutoriel sur lequel je me suis principalement basé est disponible ici.

RPX -  RPXNow.com

, , ,

No Comments

stackoverflow.com

Le concept de base de stackoverflow est vieux : Site de dépôt de questions orienté autour du développement  informatique, le principe est simple : une fois inscrit, il est possible de poser des questions, et les autres utilisateurs peuvent vous répondre. Le service est gratuit et le design simple et clair (ce qui manque parfois dans ce genre de service), mais jusque la, rien de bien extraordinaire. Ah oui, le nom est cool aussi.

stackoverflow

Il faut quand même noter que le site est très jeune ( moins d’un an ) et compte déja 3.5 millions de visiteurs uniques par mois. Autant dire que ça va pas trop mal.

Alors, comment expliquer ce succès ? C’est assez simple : la ou la majorité des autres sites du genre sont souvent faits par des gens en 3 pièces pour tenter d’amasser des thunes, stackoverflow est fait par des gens qui ont compris ce qui attiraient les geeks. Remarque, quand on voit les photos du staff (scroller un peu en bas), on comprend assez vite pourquoi. Ca a l’air d’être une bien belle brochette :-)

La réputation

La première chose est  l’utilisation d’une “monnaie” interne, la réputation, qui fonctionne de la manière suivante:

Lorsque vous posez ou que vous répondez à une question, les autres utilisateurs ont la possibilité de voter pour votre contribution, soit positivement, soit négativement. Ces votes augmentent ( ou diminuent ) ainsi votre réputation.

good_answer

Cette réputation représente ainsi, pour reprendre les termes du site, “A quel point la communauté Stack Overflow vous fait confiance” (”how much the Stack Overflow community trusts you”).

Elle permet aussi d’accéder à certains privilèges. Par exemple, une fois les 200 réputations atteints, le nombre de pubs qui vous est affiché sur le site est diminué (j’aime bien l’idée),  et une fois les 2000 atteints, il possible d’éditer les posts des autres utilisateurs. (La liste complète est disponible ici).

Il est aussi possible de déposer une partie de sa réputation en “bounty” sur une de vos question. Si par exemple une question importante n’a pas encore eu de réponse, il vous est possible de déposer, disont 200pts de réputation dessus, qui seront ainsi une récompense pour la personne qui vous donnera la réponse attendu. Les questions disposant de bounty sont de plus visibles dans un onglet à part, permettant de rester plus longtemps dans la ou les premières pages.

Les badges

L’autre concept est le système des badges. En effet certaines actions vous attribuent des badges, qui sont de 3 types : bronze, argent et or.

badge

Par exemple, lors du premier vote positif sur l’une de vos réponses, vous vous voyez attribué le badge de bronze  “Teacher” (oui, ils ont même pousser le vice en nommant chacun des badges)

Cette idée démoniaque, tout droit tirée des MMORPG  (concept d’achievement de WAR ou de WOW) est l’assurance que tout bon geek va passer plus de temps sur le site à essayer de monter sa réputation et débloquer des badges qu’à réellement bosser en semaine. Balaise. Vraiment balaise.

Dernier point interessant, il faut savoir que la base de donnée de stackoverflow est disponible en download libre, via torrent. Le post avec les mises à jour mensuelles est ici.

Serverfault.com

Stackoverflow dispose également d’un autre site, serverfault.com, qui lui est orienté vers les administrateurs système, et qui fonctionne sur le même principe.

serverfault

Superuser.com

Et pour finir, un troisième site est prévu pour bientôt pour clôturer la trilogy stack overflow : Superuser.com , qui lui ciblera, litéralement : “computer enthusiasts and power users”

superuser

No Comments

Upgrade wordpress 2.8

Allez, pour la résurrection, mise à jour de wordpress de 2.5 ( ou 2.4 je sais même plus ) à 2.8

Feedback d’un mec qui n’a jamais codé une ligne de PHP :

- Trouver la doc sur leur site et la lire : 5 minutes

- Retrouver son login et son mdp unix : 7 minutes

- Trouver les identifiants sql dans la config : 30 secondes

- Installer MySql Administrator en local : 3 minutes

- Faire le back de la base : 25 secondes

- Faire le backup des fichiers : 2 minutes

- Mettre à jour les fichiers WP : 8 minutes

- Migrer la base : 3 secondes

Conclusion : y a des framework qui devraient en prendre de la graine…

No Comments

Positeo.com

Je sais plus trop comment je suis tombé sur le site, mais j’ai trouvé l’idée cool.

Positeo propose un service de vérification de son référencement google.

On choisi son mot clef, le site cible, et positeo nous indique la position du site sur une recherche du mot clef choisi.

Par exemple avec le mot clef ‘chaussures’ positeo nous indique que le site sarenza.com  est en première position (quelle surprise !) et eram.fr en 8ème.

Autant pour des sites se trouvant en première page de google, on ne gagne pas spécialement de temps par rapport à une recherche à la main, autant si le site recherché se trouve plus loin, cela evite de se tapper le défilement des pages jusqu’à trouver le résultat voulu.

Autre détail pratique, les mots clefs et sites déjà utilisés sont mémorisés, ce qui permet d’eviter de les retapper à chaque fois.

A noter également que le service va vérifier les résultats sur plusieurs datacenter google ( 15 aléatoires par requête ), même si je suis pas sur de l’interet de la chose.

,

No Comments

Javascript et les arguments optionnels

Arguments optionnels

Une astuce que je viens d’utiliser il y a quelques minutes et sur laquelle j’avais dis que j’ecrirais une introduction..
La voila donc.

Mettont que nous ayons besoin de trier une liste. Pour ce faire, nous créons une méthode qui s’occupe de trier la liste, puis de la retourner ( dans l’exemple, la fonction fait juste appel à la méthode sort de la liste, mais on imagine la déclaration d’une vrai méthode de tri puis de son exécution )

On obtientrait donc quelque chose de ce type :

mySort = function(l){
    l.sort();
    return l;
};
>>> mySort([4,2,3]);
[2,3,4]

Cependant, plus tard lors de notre développement, apparait un autre besoin : il faudrait pouvoir trier la liste, mais en sens inverse cette fois-ci.

Plusieurs solutions apparaissent alors :

La premiere serait de séparer les deux étapes, en effectuant d’abord l’appel à mySort(), puis ensuite à myReverse() par exemple ( qui, ferait d’ailleurs simplement return l.reverse() dans cet exemple très basique ). Mais cela allourdirait le code.

La seconde est de rajouter un second paramètre à mySort, pour spécifier l’ordre dans lequel on veut trier la liste.
On obtiendrait alors quelque chose de ce genre :

mySort = function(l, order){
    l.sort();
    if(order=="reverse") l.reverse();
    return l;
};
>>> mySort([2,4,3], "normal")
[2,3,4]
>>> mySort([2,4,3], "reverse")
[4,3,2]

On observe effectivemment qu’en fonction du second paramètre ( “normal” ou “reverse” ), le sens du tri est, ou non, inversé.

Seulement voila, cela oblige à passer un second parametre à chaque appel de sa méthode. Paramètre au final inutile si on veut trier la liste ’simplement’, sans l’inverser.

Et bien en fait (oh surprise!) non.

En effet, une astuce trop peu connue des débutants est l’utilisation de paramètres optionnels. Un paramètre contenu dans la déclaration d’une méthode et non envoyé lors de l’appel de cette dernière ne pose,en fait, pas de problème. La variable est simplement considérée comme étant à la valeur null.

exemple :

f = function(a){
    return a
}
>>> f(2)
2
>>> f()
null

On constate qu’effectivemment, quand le paramètre ‘a’ n’est pas envoyé à la fonction ‘f’, ‘a’ est quand meme défini, et a la valeur null, dans le corps de la fonction. En exploitant cela, on peut modifier notre méthode de tri pour obtenir la suivante :

mySort = function(l, reverse){
    l.sort();
    if(reverse) l.reverse();
    return l;
};
>>> mySort([2,4,3])
[2,3,4]
>>> mySort([2,4,3], "reverse")
[4,3,2]

A noter qu’ici, la variable reverse est utilisé comme un flag : dans l’exemple on lui donne la valeur “reverse”, mais un simple “true” aurait suffit ( même si “reverse” aide à la lisibilitée du code )

Utilisation de la variable argument

Au passage, une autre astuce (un peu plus avancée celle la) concernant les arguments en javascript : dans une fonction, la variable ‘arguments’ contient la liste des arguments qui ont été passés.

Très simplement :

myTest2 = function(){
    return arguments;
};
>>> myTest2()
null
>>> myTest2(1,2,3)
[1,2,3]

Et cela marche quelque soient les arguments ‘normallement’ définis :

myTest2 = function(a,b){
    return arguments;
};
>>> myTest2()
null
>>> myTest2(1,2,3)
[1,2,3]

Arguments est une liste tout ce qu’il y a de plus classique : on peut connaitre sa taille avec arguments.length, et on recupère un élement avec arguments[position].

Concretement, cela permet d’envoyer un nombre variable de paramètres.

Par exemple, on peut envisager une fonction qui additionne un nombre quelconque de variables.

Additionner = function(){
    var sum = 0;
    for(var i=0; i < arguments.length; i++){
        sum += arguments[i];
    }
    return sum;
};
>>> Additionner()
0
>>> Additionner(1,2)
3
>>> Additionner(1,2,3)
6
>>> Additionner(1,2,3,6,12,48)
72

On constate bien qu’on peut passer un nombre variable de paramètres, et que le résultat de la méthode est la somme de tous.

Spark.

No Comments

Bien connaitre le type d’une variable javascript : les limites de typeof

Lorsqu’on commence à faire du javascript, il arrive forcement un moment ou l’on à besoin de connaitre le type d’une variable avec laquelle l’on travaille. Cela peut être par exemple pour du passage de paramètres multitypés, ou lors de l’utilisation de paramètres optionnels, Ou l’ont a parfois besoin de vérifier ce qui a réellement été passé dans les args.

En recherchant sur google, on tombe vite sur ce qui semble être la solution au problème : en effet, javascript dispose d’une méthode typeof, retournant une string identifiant le type de l’élément.

exemples :

>>> typeof 1
"number"
>>> typeof "hello"
"string"

Jusque la, tout va bien. Cependant, les surprises arrivent dès qu’on pousse les tests un peu plus :

>>> typeof [1,2,3]
"object"

Tiens, il considère ma liste comme un objet !

>>> typeof new Date()
"object"

Et les dates aussi !

>>> typeof null
"object"

Même null est considéré comme etant du type object…

En effet, l’opérateur typeof n’identifie que les types suivants :

"number"
"string"
"function"
"boolean"
"object"

Dans la pratique, on a besoin de pouvoir faire la difference entre une liste et un objet, ou de savoir si un paramètre est une date, ou si le retour d’une méthode est une erreur, par exemple.

La solution consiste donc à bricoler sa propre méthode typeof, pour avoir une identification plus précise des variables. Concrètement, pour identifier un type, on va chercher une bidouille sur la variable à chaque fois.

Par exemple :

Pour les dates c’est très simple, on regarde si le constructeur est bien ‘Date’.

if( var.constructor==Date) // it's a date.

Pour les listes, on pourrait faire pareil ( regarder si le constructeur est bien ‘Array’ ), cependant cela peut poser problème dans certains cas. les selecteurs jQuery, par exemple, sont des listes (on peut faire selecteur[0]), mais sont crées à partir du constructeur object.
Pour les identifier, on vérifie donc à la place la présence d’un attribut ‘length’ sur la variable testée

if (el.length) // it's a list 

Pour null, on fait juste un test avec la variable null !

if (var==null) // it's null !

Il reste deux autres pseudotypes, moins utilisés, mais qu’il peut être tout de même utile de dissocier :

Les erreurs (utile en cas de retour dans un catch par exemple)
La classe erreur est spécifique au navigateur (evidemment), cependant, sous tous, elle dispose toujours de deux attributs : ‘message’ et ‘name’. On verifie donc la présence de ces deux attributs, et pour bien faire, on vérifie bien la présence de “Error” dans l’attribut nom.

if(el.message!=null && el.name!=null && el.name.search("Error")>-1) return 'error';

Et pour finir, les noeuds DOM. La aussi, c’est de la bidouille : on verifie l’existence d’un attribut nodeName ou tagName sur la variable.

if(el.nodeName || el.tagName) return 'node'; // it's a node

Ce qui donne la méthode suivante :

/**
* Return 'advanced' type for an element
* Type can be of :
*  - 'null'
*  - 'string'
*  - 'number'
*  - 'boolean'
*  - 'function'
*  - 'list'
*  - 'node'
*  - 'date'
*  - 'error'
*  - 'object'
* @param el
**/
typeOf = function(el){
var elType = typeof el;

// null type
if(el==null) return 'null';

// basic types : number, string, function
if(elType=='number'||elType=='string'||elType=='function'||elType=='boolean')
    return elType;

// date
if(el.constructor==Date) return "date";

// domElem
if(el.nodeName || el.tagName) return 'node';

// list
if(el.length) return 'list';

// error
if(el.message!=null && el.name!=null && el.name.search("Error")>-1) return 'error';

// object
return 'object';
}

Et voila, une fonction typeOf qu’elle est mieux que l’originale !

>>> typeOf([1,2,3])
'list'
>>> typeOf(null)
'null'
>>> typeOf(document.body)
'node'
>>> typeOf(new Date())
'date'

Et les type originels sont identifiés aussi :

>>> typeOf(1)
'number'
>>> typeOf('hello')
'string'
>>> typeOf(String)
'function'
>>> typeOf(true)
'boolean'

Voila, comment gagner pas mal de temps sur les verifs avec une méthode de 10 lignes !

No Comments

Naissance de Way Of Spark

Bah voila, après avoir cherché un moteur de blog déja développé pour AppEngine, puis d’avoir commencé de coder mon propre moteur ( et de l’avoir foutu au placard avec les autres trucs abandonnés ), je me suis résigné à squater le dédié d’un pote pour m’y faire mettre un wordpress ( merci à nevare au passage ). C’est moins folichon qu’avoir un blog qu’on a codé sois même, mais au moins, ca c’est fait !

Je sais même pas encore de quoi je vais parler précisemment, à priori ca sera du web, du design, et un peu d’e-commerce ( on va essayé de mettre de coté le 3615 malife, mais qui sais !)

Bref, longue vie à mon blog !

2 Comments