ããã«ã€ããŠã¯ã FeathersCrowããŒããããã®æŽæ°ã§ããå°ãæžããŸããã ãã®åé¡ã¯ã次ã®ããŒãžã§ã³ã®FeathersèªèšŒã§ã«ããŒããããã¹ãŠã®é¢é£ããåé¡ãåéããããšãç®çãšããŠããŸãã
çŸåšã®ïŒBuzzardïŒãªãªãŒã¹ã§ã¯ãFeathersã³ã¢ã¯å®å šã«ãã¬ãŒã ã¯ãŒã¯ã«äŸåããªããªããŸããããèªèšŒãã©ã°ã€ã³ã¯ãŸã äžéšã®Expressããã«ãŠã§ã¢ãç»é²ããŠããŸãã 次ã®ããŒãžã§ã³ã§ã¯ãããã«ãŠã§ã¢ã¯@ femalesjs / expressã«ç§»è¡ããèªèšŒã³ã¢ããã¬ãŒã ã¯ãŒã¯ã«äŸåããªããªããŸãã ããã«ãããKoaãMQTTãªã©ã®æ°ãããã©ã³ã¹ããŒããå¯èœã«ãªããŸãã
çŸåšãWebSocketã¯ãã«ã¹ã¿ã ã€ãã³ãã¡ã«ããºã ãä»ããŠèªèšŒããã³ãã°ã¢ãŠããããŸãã ããã«ãããç¹ã«ãµãŒããŒãšã¯ã©ã€ã¢ã³ãã®äž¡åŽã§ã®ä¿¡é Œæ§ã®é«ãåæ¥ç¶ã«é¢ããŠãããã€ãã®åé¡ïŒããšãã°ããŸããªãèªèšŒããŒã¯ã³ãªãããšã©ãŒïŒãçºçããŠããŸããã
ããã«ãããã¹ããŒããã«ã¢ã¯ã»ã¹ããŒã¯ã³ãžã®äŸåããªããªãããœã±ããã®åèªèšŒãé©åã«åŠçãããŸãã
Feathersã¯ãèªèšŒã«JWTã䜿çšããŠAPIãäœæããããã®ã©ã€ãã©ãªã§ãã éåžžã®Feathersã»ããã¢ããã§Cookieã䜿çšãã1ã€ã®äŸã¯ãoAuthïŒFacebookãGoogleãªã©ïŒèªèšŒãããŒã®åŸã«JWTããã©ãŠã¶ãŒã«æž¡ãããšã§ãã æ°ããoAuthããã³èªèšŒã¯ã©ã€ã¢ã³ãã¯Cookieã䜿çšããªããªãããã¹ãŠãäžåºŠã«å®è¡ããããšããã®ã§ã¯ãªããoAuthãããŒã2ã€ã®éšåã«åå²ããŸãã oAuthã¢ã¯ã»ã¹ããŒã¯ã³ã¯ãã¯ãã¹ãã¡ã€ã³å¯Ÿå¿ã®ïŒããŒã«ã«ã§ã®ã¿ã¢ã¯ã»ã¹å¯èœãªïŒURLããã·ã¥ã«èšå®ãããFeathersã®æšæºèªèšŒã¡ã«ããºã ã䜿çšããŠJWTãšäº€æã§ããŸãã
ãã¹ãŠã®èªèšŒèšå®ãå®è¡æã«è©äŸ¡ãããããã«ãªã£ããããåçã«èšå®ã§ããäžèŠãªãªãã·ã§ã³ã®ãšã©ãŒã¯çºçããŸããã ãŸããã«ã¹ã¿ã èªèšŒãµãŒãã¹ãæž¡ãããšãã§ããŸãã
æ¢åã®JWTã§ã®æŽæ°ãèš±å¯ãã代ããã«ãæšæºã®èªèšŒãµãŒãã¹ã¯ããé·å¯¿åœã®æŽæ°ããŒã¯ã³ãè¿ãããã«ãªããŸããã ããŒã¯ã³ã®ãã©ãã¯ãªã¹ãã¯åŒãç¶ãæåã§å®è£ ããå¿ èŠããããŸãããæ°ããèªèšŒãµãŒãã¹ã®ã¡ãœãããä»ããŠçµ±åããæ¹ãç°¡åã§ãã
ãã®ãã£ã¹ã«ãã·ã§ã³ã¯ïŒ844ã§å§ãŸãã httpsïŒ //github.com/feathersjs/feathers/issues/844#issuecomment -390123148ã§ããããçºçããçç±ãèŠçŽããŠã
Passportãåé¿ããããšãªããFeathersã¯HTTPã©ã€ãã©ãªããã®ä»ã®ãã©ã³ã¹ããŒãã¡ã«ããºã ïŒMQTTãP2Pæ¥ç¶ãªã©ïŒã®äžã«ç°¡åã«é 眮ã§ããé¢å¿ã®åé¢ãæ確ã«ããç解ãšã«ã¹ã¿ãã€ãºãã¯ããã«ç°¡åãªèªèšŒã¡ã«ããºã ãæäŸããŸãã
params.authentication
ãã§ã¶ãŒåŽã§ã¯ããµãŒãã¹åŒã³åºãã§params.authentication
ãèšå®ããããšããèªèšŒæ
å ±ãæäŸããå¯äžã®æ¹æ³ã«ãªããŸãã params.authentication
ã«ã¯ããµãŒãã¹ã³ãŒã«ã®èªèšŒã«å¿
èŠãªæ
å ±ãå«ãŸãããã§ã«äœ¿çšãããŠãã{ strategy: 'local', email: 'email', password: 'password' }
ã®åœ¢åŒã«ãªããŸãã
// Call `find` with a given JWT
app.service('messages').find({
authentication: {
strategy: 'jwt',
accessToken: 'someJWT'
}
});
åŒã³åºãå
ïŒRESTãŸãã¯WebSocketãã©ã³ã¹ããŒããããã¯ãåäœãã¹ããªã©ïŒã¯ã params.authentication
åæ Œãã責任ããããŸãã ããã¯ã authenticate
ããã¯ãå
éšåŒã³åºãã«å¯ŸããŠå®è¡ããããã©ããããŸãã¯èªèšŒæ
å ±ãå®éã«ã©ãããæ¥ãŠãããã«ã€ããŠãæ··ä¹±ããªããªãããšãæå³ããŸãã
authenticate
ããã¯authenticate
ããã¯ã¯åŒãç¶ãååšããŸãã ããã¯æŠç¥åã®ãªã¹ããåããã©ã¡ããã«ãªããŸã
params
ããŒãžããŸããŸãã¯ããã¹ãŠã®æŠç¥ã倱æããå Žåã«å€±æããæåã®æŠç¥ã®ãšã©ãŒãã¹ããŒããŸã
params.authentication
ã«strategy
ååãå«ãŸããŠããå Žåããã®æŠç¥ã®ã¿ãåŒã³åºãããŸãã ãã以å€ã®å Žåã¯ããã¹ãŠã®æŠç¥ãåŒã³åºãããŸãã params.authentication
ããŸã£ããèšå®ãããŠããªãå Žåãããã¯ã¯
å€éšåŒã³åºãã®ãšã©ãŒãã¹ããŒããŸã
params.user
æåã§èšå®ããå ŽåïŒapp.service('messages').hooks({
before: authenticate('jwt', 'local', 'anonymous')
});
åºæ¬èªèšŒæŠç¥ãæã€ãªããžã§ã¯ãã§ããauthenticate
ã®ããŒã¿ãååŸããæ¹æ³params.authentication
ããæåã®ãªããžã§ã¯ããè¿ããããããæåããªãã£ãå Žåã¯ãšã©ãŒãã¹ããŒãããŸãã
const { Forbidden } = require('@feathersjs/errors');
const daveStrategy = {
async authenticate (authParams) {
const { username, password } = authParams;
if (username === 'david' && password === 'secret') {
return {
user: {
name: 'Dave',
admin: true
}
};
}
throw new Forbidden('Not super Dave');
}
};
app.authentication.registerStrategy('superdave', daveStrategy);
authenticate
ããã¯ã§ã¯ãè¿ããããªããžã§ã¯ãããµãŒãã¹åŒã³åºãparams
ããŒãžãããããããã®äŸã§ã¯params.user
ãŸãã
èªèšŒæŠç¥ã«ã¯ãè¿œå ã®ã¡ãœãããå éšã«å«ããŠåŒã³åºãããšãã§ããŸãã ãã§ã¶ãŒæŠç¥ã¯ãæ¡åŒµã«ãã£ãŠã«ã¹ã¿ãã€ãºã§ããã¯ã©ã¹ãšããŠå®è£ ãããŸãïŒããã«ãããæ€èšŒè ã眮ãæããããåºæ¬çã«æŠç¥ãšæ€èšŒè ã1ã€ã®ã¯ã©ã¹ã«çµåãããŸãïŒã
class LocalStrategy {
constructor(app);
async findUser(authParams);
async comparePassword(user, password);
async authenticate (authParams);
}
class MyLocalStrategy extends LocalStrategy {
async findUser(authParams);
}
app.authentication.registerStrategy('local', new MyLocalStrategy(app));
ã¹ãã©ããžãŒã¯ãåºæ¬çãªããŒãHTTPãªã¯ãšã¹ããšã¬ã¹ãã³ã¹ãååŸãã params.authentication
ïŒãŸãã¯null
ïŒã®å€ãè¿ãparse
ã¡ãœãããæäŸããããšãã§ããŸãã
const daveStrategy = {
async authenticate (authParams) {
throw new Forbidden('Not super Dave');
}
async parse (req, res) {
const apiKey = req.headers['x-super-dave'];
if (apiKey) {
return {
strategy: 'superdave',
apiKey
}
}
return null;
}
};
HTTPã©ã€ãã©ãªã¯ããããã®ã¡ãœããã䜿çšããŠparams.authentication
ããç¬èªã®ããã«ãŠã§ã¢ãèªèšŒãããã©ãããããã³ã©ã®ããã«äœ¿çšãããã決å®ã§ããŸãã
app.authenticate(authParams, [ strategies ])
ã¯ãæå®ãããèªèšŒãã©ã¡ãŒã¿ãŒã䜿çšããŠãæå®ãããæŠç¥ãå®è¡ããŸãã
// Will return the user for a JWT (on the server)
const { user } = app.authenticate({ accessToken }, 'jwt');
ãµãŒãã¹ã³ãŒã«ã§
params.authentication
ãèšå®ããããšã¯ãèªèšŒæ å ±ãæäŸããããã®_å¯äžã®_æ¹æ³ã«ãªããŸãã
service()
åŒã³åºãããšã«accessToken
ãæäŸããå¿
èŠãããçç±ã«ã€ããŠãèšèšãã€ã³ãã説æããŠservice()
ãŸããïŒ
ããã¯ãµãŒããŒã«ã®ã¿é©çšãããèªèšŒãæ§æããããšãã¹ãŠã®ãµãŒãã¹åŒã³åºãã«èšå®ãããparams.provider
ãšparams.headers
ïŒWebSocketã®å Žåã¯ããã¯åœã®ããããŒã®ã¿ïŒãä»ããŠæé»çã«çºçããŸãã ããã¯ããã©ã³ã¹ããŒããããã³ã«ã«äŸåããªãããã¯ãšãµãŒãã¹ãšå®éã®ãã©ã³ã¹ããŒãã¡ã«ããºã ïŒExpressãSocket.ioã䜿çšããHTTPãªã©ïŒãšã®éã®Feathersã®åé¢ãå£ããããšãã°authenticate('jwt')
ããã¯ãå®éã«å®è¡ããããããäœã®ããã«äœ¿çšãããŠããããéåžžã«æ··ä¹±ãããŸãããã®èªèšŒæ
å ±ã
䜿ããããã«é¢ããŠã¯ãå€éšåŒã³åºããŸãã¯å
éšåŒã³åºãã§å®éã«ã¯äœãå€ãããŸãããããµãŒããŒã§authenticate
ããã¯ãæ瀺çã«ããªã¬ãŒããå Žåã¯ããã€ã§ãparams.authentication
èšå®ã§ããŸãã ããã¯ãExpress以å€ã®æ°ãããã¬ãŒã ã¯ãŒã¯ãã©ã°ã€ã³ïŒKoaãHTTP2ãã¡ãã»ãŒãžã³ã°ãã¥ãŒãªã©ïŒã«ãšã£ãŠç¹ã«éèŠã§ãããããã®ãã©ã°ã€ã³ã«ã¯ãèªèšŒæ
å ±ãFeathersèªèšŒã¡ã«ããºã ã«æž¡ãããã®æšæºåãããæ¹æ³ããããŸãã
èªèšŒã¯ã©ã€ã¢ã³ãã¯ã app.authenticate()
åŒã³åºããŠãã°ã€ã³ããåŸããèªèšŒãããèŠæ±ãè¡ããŸãã
æ確ã«ããŠããã ãããããšãããããŸãã v3ãç¹ã«socket.io ReactNativeã¯ã©ã€ã¢ã³ãã§ã®ãã¹ããéåžžã«æ¥œãã¿ã«ããŠããŸãã
ãã¬ãªãªãŒã¹ã«é¢ããæ å ±ã¯ééããªãããã«ãããŸãã èªèšŒãããWebSocketããã確å®ã«åŠçããå¿ èŠãããèªèšŒã¯ã©ã€ã¢ã³ãããŸãšããã ãã§ãã ãããå®äºããããæ°ããã³ã¢+ããŒã«ã«ããã³jwtèªèšŒã®ãã¹ãã«åœ¹ç«ã€ããšãããã°çŽ æŽããããšæããŸãã ãã®åŸãoAuthãããã«ãã©ããŒãããã¯ãã§ãã
ããŒãžã§ã³3ãåºãã®ã¯ãã€ã§ããïŒ
ç§ã®è³ªåãžã®åçã¯ãããŸããïŒ
ãã¹ã¿ãŒãã©ã³ãã§çŸåšã®é²æç¶æ³ã確èªã§ããŸããããŒã¿ãã¹ã¿ãŒãè©ŠããŠã¿ãããšãã§ããããã«ãªã£ãããããã°æçš¿ãå ¬éããŸãã ã¹ããŒã¿ã¹ã¯æ¬¡ã®ãšããã§ãã
| ã¢ãžã¥ãŒã«| ã³ãŒã| ããã¥ã¡ã³ã| CLI
| --- |ïŒ---ïŒ|ïŒ---ïŒ| ---ïŒ|
| @ femalesjs / authentication | â
| 100ïŒ
| â|
| @ femalesjs / authentication-local | â
| 80ïŒ
| â|
| @ femalejs / authentication-oauth | â
| 90ïŒ
| â|
| @ femalesjs / authentication-client | â
| 80ïŒ
| â|
ããã«ã¡ã¯ãããã¯çŽ æŽãããã§ãïŒ
å°æ¥ã®æè»æ§ã¯çŽ æŽãããã§ãããç§ã¯ãŸã FeathersJSãããžã§ã¯ãã®èªèšŒã«èªä¿¡ããªãããããäœæããããã«æ··ä¹±ããããã»ã¹ãçµãŠããŸãã
å®å šã§ãã¹ãæžã¿ã®å®å šãªèªèšŒå®è£ ããããšããããšã¯ãèªä¿¡ãæã£ãŠæ©èœã«é²ãããšãã§ããããšãæå³ããŸãã MeteorJSã䜿çšããæãè¯ãçç±ã®1ã€ã¯ãã¯ã©ã€ã¢ã³ãã«è³ããŸã§ã®åªããã¢ã«ãŠã³ãçµ±åã§ããã
FeatherJSã®åé¡ãèŠããšãå€ãã¯èªèšŒã«é¢ãããã®ãªã®ã§ããã®äœæ¥ãçéžããããšã«è奮ããŠããŸãã
ä»æ¥ã®FeathersJSã®å®å šãªå®å šãªèªèšŒã·ã¹ãã ïŒããŒã«ã«èªèšŒãã¢ã¯ã»ã¹å¶åŸ¡ãé»åã¡ãŒã«ãªã©ïŒã®æè¯ã®ããã¥ã¡ã³ãïŒãŸãã¯ãªãã¡ã¬ã³ã¹å®è£ ïŒã¯ã©ãã«ãããŸããïŒ
ããã¯ç§ããããŸã§ã«æã£ãŠãããã®ã§ã-ãã£ãšè¯ããã®ã¯ãããŸããïŒ
2018 / 02-FeathersJSã§ã®é»åã¡ãŒã«æ€èšŒã®èšå®ïŒ2017幎ã®èšäºã®åããã·ã¥ïŒ
2018 / 02-äžèšã®èšäºããã®ãªããžããª
2017 / 01-FeathersJSã§ã¡ãŒã«æ€èšŒãèšå®ããæ¹æ³ïŒå£ããŠããŸãïŒ
2018 / 06-Feathersjsã䜿çšããVueèªèšŒ
åãã£ãŠæè¬ããŸãïŒ
ããã§ãé¢é£ãããã¹ãŠã®åé¡ã解決ãããææ¡ããããã¹ãŠã®å€æŽãå®è£ ãããFeathersv4ã®ãã¬ãªãªãŒã¹ããã¹ãã«å©çšã§ããããã«ãªããŸããã 詳现ã«ã€ããŠã¯ã移è¡ã¬ã€ããåç §ããŠãã ããã
æãåèã«ãªãã³ã¡ã³ã
ãã¹ã¿ãŒãã©ã³ãã§çŸåšã®é²æç¶æ³ã確èªã§ããŸããããŒã¿ãã¹ã¿ãŒãè©ŠããŠã¿ãããšãã§ããããã«ãªã£ãããããã°æçš¿ãå ¬éããŸãã ã¹ããŒã¿ã¹ã¯æ¬¡ã®ãšããã§ãã
| ã¢ãžã¥ãŒã«| ã³ãŒã| ããã¥ã¡ã³ã| CLI
| --- |ïŒ---ïŒ|ïŒ---ïŒ| ---ïŒ|
| @ femalesjs / authentication | â | 100ïŒ | â|
| @ femalesjs / authentication-local | â | 80ïŒ | â|
| @ femalejs / authentication-oauth | â | 90ïŒ | â|
| @ femalesjs / authentication-client | â | 80ïŒ | â|