Professional Documents
Culture Documents
js,
Express,Bootstrap&Stormpathin15
Minutes
byRobertDamphousseonOctober272014
WhatisStormpath?
StormpathisanAPIservicethatallowsdeveloperstocreate,edit,andsecurelystoreuseraccounts
anduseraccountdata,andconnectthemwithoneormultipleapplications.OurAPIenablesyouto:
Authenticateandauthorizeyourusers
Storedataaboutyourusers
Performpasswordandsocialbasedlogin
Sendpasswordresetmessages
IssueAPIkeysforAPIbasedwebapps
Andmuchmore!CheckoutourProductDocumentation(https://docs.stormpath.com/home/)
Inshort:wemakeuseraccountmanagementaloteasier,moresecure,andmorescalablethanwhat
youreprobablyusedto.
Readytogetstarted?Registerforafreedeveloperaccountathttps://api.stormpath.com/register
(https://api.stormpath.com/register)
Startyourproject
GotyourStormpathdeveloperaccount?Great!Letsgetstarted..vroomvroom
IfyoudontalreadyhaveNode.jsonyoursystemyoushouldheadovertohttps://nodejs.org
(https://nodejs.org)andinstallitonyourcomputer.InourexampleswewillbeusingaMac,all
commandsyouseeshouldbeenteredinyourTerminal(withoutthe$infrontthatsasymboltolet
youknowthattheseareterminalcommands)
Steponeistocreateafolderforthisprojectandchangeintothatdirectory:
$mkdirmywebapp
$cdmywebapp
Nowthatweareinthefolderwewillwanttocreateapackage.jsonfileforthisproject.Thisfileisused
byNode.jstokeeptrackofwhatlibraries(akamodules)yourprojectdependson.Tocreatethefile:
$npminit
Youwillbeaskedaseriesofquestions,formostofthemyoucanjustpressentertoallowthedefault
valuetobeused.HereiswhatIchose,Idecidedtocallmymainfile app.js ,Isetmyown
descriptionandsetthelicensetoMITeverythingelseIjustpressedenteron:
Press^Catanytimetoquit.
name:(mywebapp)
version:(0.0.0)
description:Websiteformynewapp
entrypoint:(index.js)app.js
testcommand:
gitrepository:
keywords:
author:
license:(ISC)MIT
Abouttowriteto/private/tmp/mywebapp/package.json:
{
"name":"mywebapp",
"version":"0.0.0",
"description":"Websiteformynewapp",
"main":"app.js",
"scripts":{
"test":"echo\"Error:notestspecified\"&&exit1"
},
"author":"",
"license":"MIT"
}
Isthisok?(yes)yes
WiththatIwillnowhaveapackage.jsonfileinmyfolder.Icantakealookatwhatsinit:
$catpackage.json
{
"name":"mywebapp",
"version":"0.0.0",
"description":"Websiteformynewapp",
"main":"app.js",
"scripts":{
"test":"echo\"Error:notestspecified\"&&exit1"
},
"author":"",
"license":"MIT"
}
Looksgood!Nowletsinstallthelibrarieswewanttouse.Youcaninstallthemallwiththiscommand:
$npmisaveexpressexpressstormpathjadeformscsurfxtend
Thesaveoptionwilladdthismoduletoyourdependenciesinpackage.json.Hereiswhateach
moduledoes:
Express.js(http://expressjs.com/)isthewebframeworkthateverythingelseisbuilton
Expressstormpath(https://github.com/stormpath/stormpathexpress)providesconvenience
featuresthatcanbetiedintotheExpressapp,makingitveryeasytouseStormpathsfeatures
inExpress
Jade(http://jadelang.com/)isatemplatingengineforwritingHTMLpages
Forms(https://github.com/caolan/forms)isamodulethatwilltakethepainoutofvalidating
HTMLforms
Csurf(https://github.com/expressjs/csurf)addsCSRFprotection
(http://en.wikipedia.org/wiki/Crosssite_request_forgery)toourforms
XtendisautilitylibrarythatmakesiteasytocopypropertiesfromoneJavaScriptobjectto
another.
GatheryourAPICredentialsandApplication
Href
TheconnectionbetweenyourappandStormpathissecuredwithAPIKeyPair.Youwillprovide
thesekeystoyourwebappanditwillusethemwhenitcommunicateswithStormpath.Youcan
downloadyourAPIkeypairinourAdminConsole(https://api.stormpath.com).Afteryouloginyoucan
downloadyourAPIkeypairfromthehomepage,itwilldownloadthe apiKey.properties filewewill
usethisinamoment.
WhileyouareintheAdminConsoleyouwanttogetthehrefforyourdefaultStormpathApplication.In
Stormpath,anApplicationobjectisusedtolinkyourwebapptoyouruserstoresinsideStormpath.All
newdeveloperaccountshaveanappcalledMyApplication.ClickonApplicationsintheAdmin
Console,thenclickonMyApplication.OnthatpageyouwillseetheHreffortheApplication.Copy
thiswewillneeditshortly.
Writingtheapplicationentry(app.js)
Itstimetocreateapp.js,thiswillbetheentrypointforyourserverapplication.Youcandothatfrom
SublimeTextoryoucandothisintheterminal:
$touchapp.js
NowopenthatfileinSublimeTextandputthefollowingblockofcodeinit:
varexpress=require('express');
varstormpath=require('expressstormpath');
varapp=express();
app.set('views','./views');
app.set('viewengine','jade');
varstormpathMiddleware=stormpath.init(app,{
apiKeyFile:'/Users/robert/.stormpath/apiKey.properties',
application:'https://api.stormpath.com/v1/applications/xxx',
secretKey:'some_long_random_string',
expandCustomData:true,
enableForgotPassword:true
});
app.use(stormpathMiddleware);
app.get('/',function(req,res){
res.render('home',{
title:'Welcome'
});
});
app.listen(3000);
YoullneedtosetthelocationofapiKeyFiletobethelocationonyourcomputerwhereyousavedthe
file.Youalsoneedtosettheapplicationhreftobetheonethatyoulookedupearlier.
The secretKey valueshouldbechangedaswell,thiswillbeusedasakeyforencryptingany
cookiesthataresetbythiswebapp.Isuggestusingalong,randomstringofanytypeofcharacter.
Inthisexampleweveenabledsomestormpathspecificoptions,theyare:
Thepasswordresetflowvia enableForgotPassword thiswillenableapasswordresetpageat
/forgot
Autoexpansionofcustomdatathiswillcomeinhandylaterwhenwebuildtheprofilepage
Therearemanymoreoptionsthatcanbepassed,andwewontcoveralloftheminthisdemo.
PleaseseeetheExpressStormpathDocumentation
(http://docs.stormpath.com/nodejs/express/index.html)forafulllist
Createyourhomepage
Letsgettheeasystuffoutoftheway:yourhomepage.Createa views directoryandthencreatea
Jadefileforthehomepage:
$mkdirviews
$touchviews/home.jade
NowopenthatfileinSublimeTextandputthefollowinginit:
html
head
title=title
link(href='//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css',re
l='stylesheet')
body
div.container
div.jumbotron
h1Hello!
ifuser
pWelcome,#{user.fullName}
p
a.small(href="profile")Editmyprofile
a.btn.btnprimary(href="/logout")Logout
else
pWelcometomyapp,readytogetstarted?
p
a.btn.btnprimary(href="/login")Loginnow
p
span.smallDon'thaveanaccount?
span
a.small(href="/register")Registernow
Thisisasimpleviewthatwillpromptanewvisitortologin,orgreetaregistereduseriftheyhave
alreadyloggedin.
Withthatwevegotsomethingwecanlookat!
RuntheserverItsAliiiive!
Ikidyounot:yourapplicationisreadytobeused.Justrunthiscommandtostarttheserver:
$nodeapp.js
Thiswillstartyourappwhichisnowrunningasawebserveronyourcomputer.Youcannowopen
thislinkinyourbrowser:
http://localhost:3000(http://localhost:3000)
Youshouldseeyourhomepagenow:
Goahead,tryitout!Createanaccount,youwillberedirectedbacktothehomepageandshown
yourname.Thenlogoutandloginagain,samething!Prettyamazing,right??
Protip:useafilewatcher
Aswemoveforwardwewillbeeditingyourserverfiles.Youwillneedtorestarttheservereachtime.
Youcankilltheserverbytyping Ctrl+C inyourTerminal.ButIsuggestusingawatcherthatwill
dothisforyou.
IreallyliketheNodemontool.Youcaninstallitglobally(itwillalwaysbereadyforyou!)withthis
command:
$npminstallgnodemon
Afterinstallation,youcanthenrunthiscommand:
$nodemonapp.js
Thiswillstartyourserverandwatchforanyfilechanges.Nodemonwillautomaticallyrestartyour
serverifyouchangeanyfilessweet!
Createtheprofilepage
AcommonfeatureofmostsitesisaDashboardorprofilepageaplacewhereyourvisitor
providesomeessentialinformation.
Forexamplepurposes,weregoingtobuildaprofilepagethatallowsyoutocollectashipping
addressfromyourvisitors.WewillleverageCustomData,oneofthemostpowerfulfeaturesof
stormpath
Tobegin,letscreateanewviewforthisdashboard:
$touchviews/profile.jade
AndaJavaScriptfilewheretheroutehandlerwilllive:
$touchprofile.js
Nowwevegotsomecopyandpasteworktodo.Thesetwofilesareprettybig,sowellexplainthem
afterthepaste.
Pastethisinto profile.js :
varexpress=require('express');
varforms=require('forms');
varcsurf=require('csurf');
varcollectFormErrors=require('expressstormpath/lib/helpers').collectFormErrors;
varstormpath=require('expressstormpath');
varextend=require('xtend');
//Declaretheschemaofourform:
varprofileForm=forms.create({
givenName:forms.fields.string({
required:true
}),
surname:forms.fields.string({required:true}),
streetAddress:forms.fields.string(),
city:forms.fields.string(),
state:forms.fields.string(),
zip:forms.fields.string()
});
//Arenderfunctionthatwillrenderourformand
//providethevaluesofthefields,aswell
//asanysituationspecificlocals
functionrenderForm(req,res,locals){
res.render('profile',extend({
title:'MyProfile',
csrfToken:req.csrfToken(),
givenName:req.user.givenName,
surname:req.user.surname,
streetAddress:req.user.customData.streetAddress,
city:req.user.customData.city,
state:req.user.customData.state,
zip:req.user.customData.zip
},locals||{}));
}
//Exportafunctionwhichwillcreatethe
//routerandreturnit
module.exports=functionprofile(){
varrouter=express.Router();
router.use(csurf({sessionKey:'stormpathSession'}));
//Captureallrequests,theformlibrarywillnegotiate
//betweenGETandPOSTrequests
router.all('/',function(req,res){
profileForm.handle(req,{
success:function(form){
//Theformlibrarycallsthissuccessmethodifthe
//formisbeingPOSTEDanddoesnothaveerrors
//Theexpressstormpathlibrarywillpopulatereq.user,
//allwehavetodoissetthepropertiesthatwecare
//aboutandthencalsave()ontheuserobject:
req.user.givenName=form.data.givenName;
req.user.surname=form.data.surname;
req.user.customData.streetAddress=form.data.streetAddress;
req.user.customData.city=form.data.city;
req.user.customData.state=form.data.state;
req.user.customData.zip=form.data.zip;
req.user.customData.save();
req.user.save(function(err){
if(err){
if(err.developerMessage){
console.error(err);
}
renderForm(req,res,{
errors:[{
error:err.userMessage||
err.message||String(err)
}]
});
}else{
renderForm(req,res,{
saved:true
});
}
});
},
error:function(form){
//Theformlibrarycallsthismethodiftheform
//hasvalidationerrors.Wewillcollecttheerrors
//andrendertheformagain,showingtheerrors
//totheuser
renderForm(req,res,{
errors:collectFormErrors(form)
});
},
empty:function(){
//Theformlibrarycallsthismethodifthe
//methodisGETthuswejustneedtorender
//theform
renderForm(req,res);
}
});
});
//Thisisanerrorhandlerforthisrouter
router.use(function(err,req,res,next){
//Thishandlercatcheserrorsforthisrouter
if(err.code==='EBADCSRFTOKEN'){
//Thecsurflibraryistellingusthatitcan't
//findavalidtokenontheform
if(req.user){
//sessiontokenisinvalidorexpired.
//rendertheformanyways,buttellthemwhathappened
renderForm(req,res,{
errors:[{error:'Yourformhasexpired.Pleasetryagain.'}]
});
}else{
//theuser'scookieshavebeendeleted,wedontknow
//theirintentionissendthembacktothehomepage
res.redirect('/');
}
}else{
//Lettheparentapphandletheerror
returnnext(err);
}
});
returnrouter;
};
Pastethisinto profile.jade :
html
head
title=title
link(
href='//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css',
rel='stylesheet'
)
body
div.container
div.pageheader
h1MyProfile
iferrors
eacherrorinerrors
div.alert.alertdanger
span#{error.error}
ifsaved
div.alert.alertsuccess
spanYourprofilehasbeensaved
form.loginform.formhorizontal(method='post',role='form')
input(name='_csrf',type='hidden',value=csrfToken)
div.formgroup
label.colsm4FirstName
div.colsm8
input.formcontrol(
placeholder='Yourfirstname',
required=true,
name='givenName',
type='text',
value=givenName)
div.formgroup
label.colsm4LastName
div.colsm8
input.formcontrol(placeholder='Yourlastname',
required=true,
name='surname',
type='text',
value=surname)
div.formgroup
label.colsm4Streetaddress
div.colsm8
input.formcontrol(placeholder='e.g.123SunnyAve',
required=true,
name='streetAddress',
type='text',
value=streetAddress)
div.formgroup
label.colsm4City
div.colsm8
input.formcontrol(placeholder='e.g.City',
required=true,
name='city',
type='text',
value=city)
div.formgroup
label.colsm4State
div.colsm8
input.formcontrol(placeholder='e.g.CA',
required=true,
name='state',
type='text',
value=state)
div.formgroup
label.colsm4ZIP
div.colsm8
input.formcontrol(placeholder='e.g.94116',
required=true,
name='zip',
type='text',
value=zip)
div.formgroup
div.colsmoffset4.colsm8
button.login.btn.btnprimary(type='submit')Save
div.pullright
a(href="/")Returntohomepage
Breakingitdown
YouvejustcreatedanExpressRouter.Saywha?IreallylikehowtheExpressmaintainershave
describedthis:
Arouterisanisolatedinstanceofmiddlewareandroutes.
Routerscanbethoughtofas"mini"applications,capableonly
ofperformingmiddlewareandroutingfunctions.Everyexpress
applicationhasabuiltinapprouter.
saywha?
Inmywords:Express4.0encouragesyoutobreakupyourappintominiapps.Thismakes
everythingmucheasiertounderstandandmaintain.Thisiswhatwevedonewiththe profile.js file
wevecreatedaminiappwhichhandlesJUSTthedetailsassociatedwiththeprofilepage.
Dontbelieveme?Readon.
Pluginyourprofilepage
BecausewefollowedtheRouterpattern,itsnowthissimpletoaddtheprofilepagetoyourexisting
app.jsfile(putitrightabovethecallto app.listen ):
app.use('/profile',stormpath.loginRequired,require('./profile')());
Omg.Yes.YES.Youvejustdecoupledtheimplentationofaroutefromitsaddressing.Holygrail?
Almost.Awesome?MostDef.(Bytheway,youvealsoforcedauthenticationonthisroute,using
Stormpath,nice!)
Restartyourseverandvisit /profile ,youshouldseetheformnow:
Breakingitdownforreal
Okay,theresaLOTmoretotalkabouthere.Soletmecovertheimportantpoints:
The profile.js fileisabuilderorconstructor,sotospeak.Youhavetoinvokeitasamethod
inordertogettherouteroutofit.Thatswhywehavethatempty () afterthe
require('./profile') statement.Whybother?Becausewiththispatternyoucanpassinany
optionsthatmayberequiredforthisrouter.Atthemomentwedonthaveany,butwhoknows
whatthefutureholds?Doingthisgiveyouroomtousethisrouterinmultiplewebappsand
factoroutanyappspecificconfig.
Weareusingthe forms librarytocreateaschemafortheprofileform.Thisisagoodpractice
becauseitseparatesthewayinwhichwevalidatefromtheformfromthewayinwhichtheform
isdisplayed.
Wrappingitup
Alas,wevereachedtheendofthistutorial.Younowhaveawebappthatcanreigsternewusersand
allowthemtoprovideyouwithashippingaddress,prettysweetright?
Followingtheprofileexampleyounowhaveeverythingyouneedtostartbuildingotherpagesinyour
application.Asyoubuildthosepages,Imsureyoullwanttotakeadvantageofsomeothergreat
features,suchas:
EnableGoogleLogin(http://docs.stormpath.com/nodejs/express/product.html#usegoogle
login)
EnableFacebookLogin(http://docs.stormpath.com/nodejs/express/product.html#use
facebooklogin)
CustomizethePasswordResetExperience
(http://docs.stormpath.com/nodejs/express/product.html#usepasswordreset)
APIKeyAuthentication(http://docs.stormpath.com/nodejs/express/product.html#api
authentication)
Thosearejustafewofmyfavorites,butthereissomuchmore!
PleasereadtheExpressStormpathProductGuide
(http://docs.stormpath.com/nodejs/express/product.html)fordetailsonhowtoimplementallthese
amazingfeaturesanddonthesitatetoreachouttous!
WELOVEWEBAPPSandwewantyourusermanagementexperiencetobe10xbetterthanyouever
imagined.
robertout
Likewhatyousee?
Follow@goStormpath
tokeepupwiththelatestreleases.
GetStartedwithStormpath
UserManagementAPIforDevelopers
TryItForFree(https://api.stormpath.com/register)
63Comments
Stormpath
Share
Recommend 5
Login
SortbyBest
Jointhediscussion
qix 2monthsago
Hi,itdoesn'tlooklikethestormpathexpressnpmdoesn'texplicitlyexposetheclient,
whichI'dliketousetomakenode.jsapicallsaswell.Isitbestpracticetojust
require('stormpath')inwhichevermoduleIneedit,andinitializeanewclienteachtime?
1
Reply Share
RandallDegges
Mod >qix
2monthsago
Heyoitdoesexposetheclientvia:`req.app.get('stormpathClient')`,youcanalso
accessitoutsideofarouteusing`app.get('stormpathClient')`.
Reply Share
qix>RandallDegges 2monthsago
Gotcha,sawthatinthecodebutwasn'tsureifthatwasthe"approved"
means.:)Thanks!
Reply Share
LuisJ amonthago
beautifultutorialcontinuetoshare
Reply Share
richie 3monthsago
Hi!HowwouldyoudothiswithHTMLandnotJade?
Reply Share
Robert>richie 3monthsago
YoucanuseEJS(whichisHTML),ourguidehasasectiononthis.Gotothislink
andscrolldownto"UsingEJS"
1
Reply Share
LilyTHERESA>Robert 2monthsago
Cannotaccessthelink.Couldyouspellitout?
Reply Share
RandallDegges
Mod >LilyTHERESA
https://docs.stormpath.com/nod...
2monthsago
Reply Share
Felipe>richie 3monthsago
Iguessyouneedtousesometemplateengineanyway
Reply Share
akhileshgupta 4monthsago
Hi,
HowcanImodify'register'and'login'views?
Therearenojadefiles
Reply Share
Robert>akhileshgupta 4monthsago
Ifyou'dliketomodify(orcompletelyreplace)ourdefaultviews,pleaseseethis
sectionofourdocumentation:https://docs.stormpath.com/nod...
Hopethishelps!
Reply Share
Vandes 5monthsago
Hi,
InoticedthatwhenImodifytheuserdataintheProfilepagetheyappeartobesaved,but
ifIrefreshorreturntothehomepagetheywillreverttothepreviousvaluesuntilIrestart
theserver.
Isthereawaytoretrieveupdateduser.customDatawithouthavingtorestart?
Sorryformynoobness,andthanksforthegreattutorial!
Reply Share
RandallDegges
Mod >Vandes
5monthsago
Thisshouldbeworking(justtesteditlocally).Isthereachancethatyoudidn't
includethe`.save()`methodcallaftertheprofileinformationgetsupdatedin
customdata?The`.save()`methodmustbecalledinorderto'persist'alldata
changestoStormpath.
Reply Share
Vandes>RandallDegges 5monthsago
HiRandall,justtobesureIcopypastedthewholecode,soIdon'tthinkI'm
missingsomething.Additionally,ifIcheckintomyStormpathaccountIcan
seetheusersofmyapplicationandthey'reupdatedinrealtime.It'sjustmy
localinstallationthatneedsaserverreboottodisplayanewlysavedname
oraddressorwhatever.
Onasidenote,howshoudIproceedifIwanteachusertohaveapublic
profilepagethatdisplaysthekindofstaticdata(name,addressand
whatnot)reachableunderauniqueurl?Robertmentionedinanother
commentthatsomethinglikethiscouldbedonewithoutanexternal
database,anditwouldbegreattohavealittleinputonthat.
Thanks!
Reply Share
RandallDegges
Mod >Vandes
5monthsago
Hmm,youmightwanttotryrunningtheexamplecodeinan
incognitotab(maybethere'sweirdbrowsercachingstuffgoingon)?
I'mjustcuriousasI'mtestingitlocallyanditworksfineweird.
Thewayyou'dhandlepublicstuffisessentiallythesameyou
don'tevenreallyneedanotherdatabase.
Whatyou'ddoisessentiallydosomethinglike:
Createadynamicrouteinexpressapp.get('/users/:email').
LookuptheStormpathuseraccountdynamically,giventheuser
suppliedemail.
Renderwhateverpagetemplateyouwantbymanuallypassing
theuserobjectyoulookupintothetemplate,eg:res.render('profle
page',user=account)
Justtreatitlikeyouwouldanyotherpublicsite=)
Reply Share
Vandes>RandallDegges 4monthsago
Aboutthepublicprofiles...I'mkindastuck.
Ican'tunderstandhowtolookupalltheusers'accountstocreate
thedynamicroute.ShouldIuseapplication.getAccounts()?
WhateverIdo,Icanonlyseemtoaccessthecurrentuser'sdata,
runningin"undefined"errorsifnotloggedin.
Reply Share
RandallDegges
Mod >Vandes
4monthsago
Ifyouwanttocreateapublicprofilepageforauser,youcandoit
usingsomethinglikethis:http://pastie.org/10122343
Reply Share
Vandes>RandallDegges 4monthsago
ThethingI'mnotgettingis:howdoIdefineusernametomakethe
routevalidforeveryuser?Thecodeasisgivesme"usernameis
notdefined",butifIdefineitmanuallythewholeprocessisuseless
becauseit'srestrictedtotheuserorcollectionIdefined.
Reply Share
RandallDegges
Mod >Vandes
4monthsago
I'mnotsurewhatyoumean,exactly?Inexpressyoucancreate
'dynamicroutes'thatallowyoutoacceptANYinput.
That'swhattheapp.get('/users/:username')stuffdoes.
That'swhattheapp.get('/users/:username')stuffdoes.
Here'safullexample:http://pastie.org/10122647
Itmeansthatifauservisitstheuser/user/rdegges,theninyour
routecodeyou'dhaveavariablecalledusernamethathasthat
parameteravailable=)
Youcanreadmoreaboutthisintheroutingguide:
http://webapplog.com/urlparam...
Reply Share
Vandes>RandallDegges 4monthsago
That'swhatIwasmissing,andIcouldn'tfindaclearexplanation.
Thanks!Nowit(kinda)worksandmostimportantlyIunderstoodthe
logic.
Itstillgivesmetheerrorintheconsole"cannotreadproperty
'fullName'ofundefined"ifIcall#{account.fullName}inthetemplate,
butdespitetheerrorthetemplaterendersfineandthefullnameis
displayed.Anyaccount.customDataItrytocall,though,isNOT
displayed.
ThecodeI'mdoingthesetestsonishere,ifyouhavetimetotakea
look.
https://bitbucket.org/hintclub...
Ialreadybotheredyoualot,sorry=(
Reply Share
Vandes>Vandes 4monthsago
Ok,solvedthisoneonmyown.
Forsomereasonitwasrenderingthetemplatetwotimes,firstwith
thecorrectusernamevariabletakenfromtheurl,andthenwithout
definingusername,thereforetheerror.
ByusingthegetCustomDatamethodpriortotherenderIsolvedthe
doublerenderingissueandalsothedisplayofcustomDataonthe
profilepage.I'llpastethefinalcodeincaseanyoneelsehasthe
sameproblem.
http://pastie.org/10125371
Reply Share
Vandes>RandallDegges 5monthsago
Noluckinincognitoeither.Justtriedthis:Editmyprofile>
changedtheStreetvalue>Save>Returntohome>Editmy
profile.TheStreetvalueisalwaystheonethatwastherewhenthe
serverwasstarted.IfIrestarttheserver,Iwillfindmymostrecent
edit.That'sverystrange,Ididthewholeprocessonadifferentlinux
edit.That'sverystrange,Ididthewholeprocessonadifferentlinux
installandtheresultisthesame...whatamIdoingwrong?:)
Hey,thanksalotforthesuggestions!
Reply Share
RandallDegges
Mod >Vandes
5monthsago
Hmm,notsurewhattosuggesttobehonest.
You'rewelcometoopenaticketwithsupport:
support@stormpath.comwecantrytodoascreensharesession
withya.That'saboutallIcanthinkof!
Reply Share
GaryHortenstine>RandallDegges 4monthsago
I'mseeingthesameexactbehaviorthatVandesdescribed.I'm
wonderingiftheremightbeanupdatetooneoftheothermodules
thatiscausingthistobeanissuerecently.Hereismy
package.json.
"dependencies":{
"bodyparser":"^1.12.0",
"csurf":"^1.8.0",
"express":"^4.11.2",
"expressstormpath":"^1.0.4",
"forms":"^1.1.1",
"jade":"^1.9.2",
"xtend":"^4.0.0"
}
1
Reply Share
GaryHortenstine>GaryHortenstine 4monthsago
Inaddition,IamalsoabletonavigatetotheprofilepageafterIhave
clicked"Logout".SoI'msittingonthewelcomepage,supposedly
notloggedin,butwhenIgototheURLaddressbarandappend
"/profile"totheend,ittakesmewithoutcomplaint.
Reply Share
Robert>GaryHortenstine 4monthsago
HiGary,
Wefiguredouttheissuehere!Ourexamplewasmissingalineof
code.Youwanttoputthislineinyourapp,rightabovewherewe
callreq.user.saveinprofile.js:
req.user.customData.save()
Thismakesthecalltosavetheuser'scustomdata.Whilethe
req.user.save()willdothesamething,itdoes'tinvalidatethecache
ofthecustomdataobject.
Hopethishelps!
Robert
Reply Share
Vandes>Robert 4monthsago
ThanksRobert,nowitworksgreat!=)
Reply Share
GaryHortenstine>Robert 4monthsago
Sweet!Thatgotit.
Thanks!!
Reply Share
GaryHortenstine>GaryHortenstine 4monthsago
Ohdoublesweet!!Thatalsotookcareoftheissueaboutnavigating
totheprofilepageafterloggingout!
Thisiscoolstuffwhenit'ssetupright!!!
Reply Share
GaryHortenstine>GaryHortenstine 4monthsago
Justaddingthatbyclosingthebrowserandreopening,Iwasthen
NOTabletomanuallynavigate.ItwouldseemtomethattheLogout
actionsshouldbeenoughtopreventthis,butthat'snothappening
fromwhereI'msitting.
Reply Share
ArjunGangisetty 5monthsago
Hi,
IusedthefollowingsnippetforimplementingFBlogininmyapp.jsfile.I'mgettingthe
followingerrorwhentryingtoruntheapplication.Cansomeone,pleaseguideme.
C:\Users\ArjunKumar\mywebapp\node_modules\expressstormpath\lib\helpers.js:576
thrownewError('ERROR:NoStormpathcredentialsspecified.')^Error:ERROR:No
Stormpathcredentialsspecified.atC:\Users\ArjunKumar\my
webapp\node_modules\expressstormpath\lib\helpers.
js:576:13
Hereisthegithublinkformycode:https://github.com/gangisettia...
ThankYou
ArjunGangisetty
Reply Share
ArjunGangisetty 5monthsago
Hi,
Imgettingthebelowerrorwhentryingtoaccesstheprofileroute.Ihavecheckedthe
dependenciesandprofilemethodinvocationinapp.js.Also,Ifollowedthethread
concerningthesameerrorandcouldn'tfigureoutproblemwithmycode.I'munsureof
what'scausingtheerror.Hereisthelinkofmysourcecode.Please,helpmeout.
https://github.com/gangisettia...
Error:misconfiguredcsrf
atgetsecret(C:\Users\ArjunKumar\mywebapp\node_modules\csurf\index.js:194:
11)atcsrf(C:\Users\ArjunKumar\mywebapp\node_modules\csurf\index.js:59:18)
atLayer.handle[ashandle_request](C:\Users\ArjunKumar\my
webapp\node_modules\express\lib\router\layer.js:82:5)
attrim_prefix(C:\Users\ArjunKumar\my
webapp\node_modules\express\lib\router\index.js:302:13)
atC:\Users\ArjunKumar\mywebapp\node_modules\express\lib\router\index.js:27
0:7atFunction.proto.process_params
(C:\Users\ArjunKumar\mywebapp\node_modules\express\lib\router\index.js:321:12)at
next(C:\Users\ArjunKumar\mywebapp\node_modules\express\lib\router\index.js:261:10)
atFunction.proto.handle
(C:\Users\ArjunKumar\mywebapp\node_modules\express\lib\router\index.js:166:3)
ThankYou
ArjunGangisetty
Reply Share
Robert>ArjunGangisetty 5monthsago
HiArjun!
Ifiguredouttheproblem,thisblogpostneedsanupdate.Inthemeantime,heres
whatyouneedtodo:
1)Theregistrationoftheprofilerouteshouldlooklikethis:
app.use('/profile',stormpath.loginRequired,require('./profile')())
2)Inprofile.js,modifythecsurf()setuptolooklikethis:
router.use(csurf({sessionKey:'stormpathSession'}))
3)Alsoinprofile.js,removeloginrequired(wemoveditinstep1),so
thislineshouldlooklikethisnowinprofile.js:
router.all('/',function(req,res){
Hopethishelps!Feelfreetoreachusonsupportifyouhaveanymorequestions!
Reply Share
ArjunGangisetty>Robert 5monthsago
HiRobert,
Ihavemadethechangesyoutold.Actually,thesessionlibrarieswere
missinginmyprojectsetupandyoursupportteamfixedthatproblem.
Now,I'mabletoruntheapplicationsmoothly.
Thanksverymuchforthehelp.
Regards
ArjunGangisetty
Reply Share
Ninz 5monthsago
Hi,
Firstofallthankyouforsharingthistutorial.
Ifollowedituntilthelastpartinprofile.js,howeverIhaveencounteredanissuesamewith
CharlesOppenheimerbelow,andIfollowedthefixesfromgithub.ButI'mstillgettingthe
samemisconfiguredcsrf.
Reply Share
Ninz>Ninz 5monthsago
Ops,mybad!Iforgottonpminstall.>.<
Reply Share
Robert 5monthsago
HiChandeep,
I'dverifythatyourStormpathAPIkeysandApplicationHrefarestillthecorrectones.If
yousillhaveproblems,feelfreetoreachusviasupport@stormpath.comsothatwecan
sharecodeandhelpyouout.Thanks!
Reply Share
Chandeep 5monthsago
Hi,
Istartedtheappanditworkedlikeacharmforthefirsttime,butwhenIrestartedthe
server,Igotsomeerrorsasbelow,can'tfigureoutwhy....pleasehelpme
/home/ckhamba/personal/miningglassdoor
information/src/FrontPanel/node_modules/express
stormpath/node_modules/stormpath/node_modules/request/index.js:50
opts=util._extend({},uri)
^
TypeError:Object#<object>hasnomethod'_extend'
atrequest(/home/ckhamba/personal/miningglassdoor
atrequest(/home/ckhamba/personal/miningglassdoor
information/src/FrontPanel/node_modules/express
stormpath/node_modules/stormpath/node_modules/request/index.js:50:17)
atRequestExecutor.executeRequest[asexecute](/home/ckhamba/personal/mining
glassdoorinformation/src/FrontPanel/node_modules/express
stormpath/node_modules/stormpath/lib/ds/RequestExecutor.js:88:3)
atdoRequest(/home/ckhamba/personal/miningglassdoor
information/src/FrontPanel/node_modules/express
seemore
Reply Share
nmtuan87 5monthsago
c:\Users\Tuan\Downloads\projectnodejs\mediacenterjsmaster\profile.js:48
router.use(csurf())
^
TypeError:Cannotreadproperty'use'ofundefined
atprofile(c:\Users\Tuan\Downloads\projectnodejs\mediacenterjsmaster\profile.js:48:11)
atObject.<anonymous>(c:\Users\Tuan\Downloads\projectnodejs\mediacenterjs
master\test1.js:27:40)
atModule._compile(module.js:460:26)
atObject.Module._extensions..js(module.js:478:10)
atModule.load(module.js:355:32)
atFunction.Module._load(module.js:310:12)
atFunction.Module.runMain(module.js:501:10)
atstartup(node.js:129:16)
atnode.js:814:3
Reply Share
Daniel>nmtuan87 2monthsago
Itisyouexpressversion,thisbecameimplementedfromv4
Reply Share
RandallDegges
Mod >nmtuan87
5monthsago
Itlookslikeyoudidn'tcreatethe`router`variable.
Reply Share
JooMartins 7monthsago
hi,Iamalsofacingthesameissuethenelen.WhenItrytoregisteranaccountiam
gettingthefollowingerror:"Oops!Weencounteredanunexpectederror.Pleasecontact
gettingthefollowingerror:"Oops!Weencounteredanunexpectederror.Pleasecontact
supportandexplainwhatyouweredoingatthetimethiserroroccurred."
Reply Share
RandallDegges
Mod >JooMartins
7monthsago
AfewthingsIwouldcheck:makesurethatyourStormpathAPIkeysand
StormpathApplicationhrefaresetupcorrectlyintheExpressapp,alsomakesure
thatyourStormpathApplicationismappedtoanenabledAccountStore.
Reply Share
Anil 8monthsago
Awesome!!Itworkedforme.Tryingtoworkon2ndtutorials,butfacingsomeproblems.
Whereineedtoaddthispartofcode,gettingconfused:
app.use(stormpath.init(app,{
enableFacebook:true,
social:{
facebook:{
appId:'xxx',
appSecret:'xxx',
},
},
}))
Ijusttriedbyaddingthatcodeintoapp.jsfile,gettingNostormpathcredentialsspecified
Reply Share
RandallDegges
Mod >Anil
8monthsago
Youleftoutafewsettingsfromthecodesnippet,youaremissingtheseones:
apiKeyFile:'/Users/robert/.stormpath/apiKey.properties',
application:'https://api.stormpath.com/v1/a...,
secretKey:'some_long_random_string',
Reply Share
Anil>RandallDegges 7monthsago
Thanksalotman...Itworkedforme...!!!!
Reply Share
elen 8monthsago
Hi,whenItrytoregisterIalwaysgetthefollowingmessage:
"Oops!Weencounteredanunexpectederror.Pleasecontactsupportand
explainwhatyouweredoingatthetimethiserroroccurred."
Idon'tknowwhyithappens.Ichecktheappwithmozillafirefox.HowcanIfixit?thanks
Reply Share
Robert>elen 8monthsago
Robert>elen 8monthsago
AfewthingsIwouldcheck:makesurethatyourStormpathAPIkeysand
StormpathApplicationHrefaresetupcorrectlyintheExpressapp,alsomakesure
thatyourStormpathApplicationismappedtoanenabledAccountStore
Reply Share
elen>Robert 8monthsago
howcanIcheckthese?thankyouinadvance
Reply Share
ClaireHunsaker
Mod >elen
8monthsago
(https://twitter.com/gostormpath) (https://github.com/stormpath)
(https://www.facebook.com/pages/Stormpath/259202314149649)
(https://plus.google.com/117311343501729372771)
About(/about)
Customers(/customers)
Blog(/blog)
Jobs(http://www.jobscore.com/jobs/stormpath)
Press&News(/press)
Contact(/contact)
Support(https://support.stormpath.com/home)
StatusReport(http://status.stormpath.com/)
Resources(/resources)
Compliance(/resources/compliance)
Security&Availability(/resources/securityand
availability)