Let's explore what it takes to do DIY authentication using Rails' has_secure_password and Rails sessions. It's more simplistic than Devise and often takes less time - freal.
a s s Y o u r C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r b e f o r e _ a c t i o n d o i f @ c u r r e n t _ u s e r . n i l ? r e d i r e c t _ t o s i g n _ i n _ p a t h , a l e r t : " P l e a s e S i g n I n " e n d e n d e n d
_ u s e r . n i l ? So, we need something that sets @ c u r r e n t _ u s e r r e d i r e c t _ t o s i g n _ i n _ p a t h So, we need a s i g n _ i n _ p a t h
c a t i o n C o n t r o l l e r < A c t i o n C o n t r o l l e r : : B a s e p r o t e c t _ f r o m _ f o r g e r y w i t h : : e x c e p t i o n b e f o r e _ a c t i o n d o @ c u r r e n t _ u s e r = U s e r . f i n d _ b y i d : s e s s i o n [ : u s e r _ i d ] e n d e n d Before every single action is executed, Rails will look at the session and get the user_id It will try to nd a User by that id, so c u r r e n t _ u s e r may be nil Every action now has access to @ c u r r e n t _ u s e r
i o n s C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r d e f n e w e n d d e f c r e a t e e n d d e f d e l e t e e n d e n d Routes g e t ' s i g n _ i n ' = > ' s e s s i o n s # n e w ' , a s : : s i g n _ i n p o s t ' s i g n _ i n ' = > ' s e s s i o n s # c r e a t e ' d e l e t e ' s i g n _ i n ' = > ' s e s s i o n s # d e l e t e '
i n if we are not already signed in. We need a form: < % = f o r m _ t a g d o % > < d i v > < % = l a b e l _ t a g : u s e r n a m e % > < % = t e x t _ f i e l d _ t a g : u s e r n a m e , p a r a m s [ : u s e r n a m e ] % > < / d i v > < d i v > < % = l a b e l _ t a g : p a s s w o r d % > < % = p a s s w o r d _ f i e l d _ t a g : p a s s w o r d , " " % > < / d i v > < d i v > < % = s u b m i t _ t a g " S i g n I n " , c l a s s : " b t n " % > < / d i v > < % e n d % >
< A p p l i c a t i o n R e c o r d h a s _ s e c u r e _ p a s s w o r d v a l i d a t e s : u s e r n a m e , p r e s e n c e : t r u e , u n i q u e n e s s : t r u e e n d This requires us to have a database eld named p a s s w o r d _ d i g e s t .
r . p a s s w o r d = ' 1 2 3 4 5 ' , it will encrypt it into p a s s w o r d _ d i g e s t You cannot reverse engineer 1 2 3 4 5 You must give the password again to see if it's correct: @ u s e r . a u t h e n t i c a t e ( " 1 2 3 4 5 " ) = > # < U s e r i d = " 3 " . . . . / > @ u s e r . a u t h e n t i c a t e ( " 4 2 " ) = > n i l
o n s C o n t r o l l e r < A p p l i c a t i o n C o n t r o l l e r d e f c r e a t e u s e r = U s e r . f i n d _ b y u s e r n a m e : p a r a m s [ : u s e r n a m e ] i f u s e r & & u s e r . a u t h e n t i c a t e ( p a r a m s [ : p a s s w o r d ] ) s e s s i o n [ : u s e r _ i d ] = u s e r . i d r e d i r e c t _ t o r o o t _ p a t h , n o t i c e : " S i g n e d i n ! " e l s e f l a s h . n o w [ : a l e r t ] = " S o m e t h i n g i s w r o n g w i t h y o u r u s e r n a m e a n d / o r p a s s w o r d " r e n d e r : n e w e n d e n d e n d
c a t i o n C o n t r o l l e r < A c t i o n C o n t r o l l e r : : B a s e p r o t e c t _ f r o m _ f o r g e r y w i t h : : e x c e p t i o n b e f o r e _ a c t i o n d o @ c u r r e n t _ u s e r = U s e r . f i n d _ b y i d : s e s s i o n [ : u s e r _ i d ] e n d d e f a u t h e n t i c a t e _ u s e r ! u n l e s s @ c u r r e n t _ u s e r d o r e d i r e c t _ t o s i g n _ i n _ p a t h , n o t i c e : " P l e a s e S i g n I n " e n d e n d d e f c u r r e n t _ u s e r @ c u r r e n t _ u s e r e n d h e l p e r _ m e t h o d : c u r r e n t _ u s e r
= i f u s e r _ s i g n e d _ i n ? % > H i < % = c u r r e n t _ u s e r % > . < % e l s e % > < % = l i n k _ t o ' S i g n U p ' , n e w _ u s e r _ p a t h % > < % e n d % >
n eld. c l a s s U s e r < A c t i v e R e c o r d : : B a s e h a s _ s e c u r e _ t o k e n e n d u s e r = U s e r . n e w u s e r . s a v e u s e r . t o k e n # = > " p X 2 7 z s M N 2 V i Q K t a 1 b G f L m V J E "
auth_token parameter. c l a s s A p i : : U s e r s C o n t r o l l e r < A p i C o n t r o l l e r b e f o r e _ a c t i o n d o @ c u r r e n t _ u s e r = U s e r . f i n d _ b y t o k e n : p a r a m s [ : a u t h _ t o k e n ] r e n d e r " A u t h T o k e n R e q u i r e d " , s t a t u s : 4 0 1 u n l e s s @ c u r r e n t _ u s e r e n d e n d
p i : : S e s s i o n s C o n t r o l l e r < A p i C o n t r o l l e r d e f c r e a t e @ c u r r e n t _ u s e r = U s e r . f i n d _ b y u s e r n a m e : p a r a m s [ : u s e r n a m e ] i f @ c u r r e n t _ u s e r & & @ c u r r e n t _ u s e r . a u t h e n t i c a t e ( p a r a m s [ : p a s s w o r d ] ) r e n d e r j s o n : { u s e r : @ c u r r e n t _ u s e r , a u t h _ t o k e n : @ c u r r e n t _ u s e r . t o k e n } , e l s e r e n d e r e r r o r s : [ " U s e r n a m e o r P a s s w o r d i s I n v a l i d " ] , s t a t u s : 4 2 2 e n d e n d e n d
/ i n i t i a l i z e r s / d o o r k e e p e r . r b D o o r k e e p e r . c o n f i g u r e d o o r m : a c t i v e _ r e c o r d r e s o u r c e _ o w n e r _ f r o m _ c r e d e n t i a l s d o U s e r . f i n d _ b y ( e m a i l : p a r a m s [ : u s e r n a m e ] ) . t r y ( : a u t h e n t i c a t e , p a r a m s [ : p a s s w o r d e n d a c c e s s _ t o k e n _ m e t h o d s : f r o m _ b e a r e r _ a u t h o r i z a t i o n , : f r o m _ a c c e s s _ t o k e n _ p a r a m g r a n t _ f l o w s % w ( p a s s w o r d ) e n d D o o r k e e p e r . c o n f i g u r a t i o n . t o k e n _ g r a n t _ t y p e s < < " p a s s w o r d "
i : : B o o k s C o n t r o l l e r < A p i : : V 1 : : A p i C o n t r o l l e r b e f o r e _ a c t i o n : d o o r k e e p e r _ a u t h o r i z e ! d e f i n d e x r e n d e r j s o n : { b o o k s : c u r r e n t _ u s e r . b o o k s } e n d p r i v a t e d e f c u r r e n t _ u s e r U s e r . f i n d ( d o o r k e e p e r _ t o k e n . r e s o u r c e _ o w n e r _ i d ) i f d o o r k e e p e r _ t o k e n e n d e n d
gem le d o o r k e e p e r 3. b u n d l e i n s t a l l 4. Add le c o n f i g / i n i t i a l i z e r s / d o o r k e e p e r . r b 5. Add to routes: u s e _ d o o r k e e p e r 6. r a i l s g e n e r a t e d o o r k e e p e r : m i g r a t i o n 7. r a i l s d b : m i g r a t e
h / t o k e n { " g r a n t _ t y p e " : " p a s s w o r d " , " u s e r n a m e " : " j w o " , " p a s s w o r d " : " 1 2 3 4 5 " } Result will have { " a u t h _ t o k e n " : " e e b d a d d b 2 c 2 d e 2 8 1 7 d b d 6 b e b e 0 6 b 0 a 7 f f a 3 4 f f d 3 8 a d e b 7 d 0 " , " e x p i r e s " : 1 2 3 4 5 6 7 8 9 0 }