loopback3已经停更了,所以如果你是初学,去看loopback4吧
为什么搞这个?因为一个项目要用,loopback国外用的多,国内没人用,但是现在手上的项目开源代码基于loopback3做的,如果自己从头做,时间成本上不划算,所以只能花时间做这个
loopback就是目前web网站前后端分离架构下的后端restful API框架,IBM做的,对标springboot,完全基于nodejs
1、应用程序目录结构
LoopBack 项目文件和目录位于应用程序根目录中。在此目录中,标准 LoopBack 项目结构具有以下子目录:
- server - 节点应用程序脚本和配置文件。
- client - 客户端 JavaScript、HTML 和 CSS 文件(仅限LoopBack 工具)。
- common - 客户端和服务器共有的文件。该/models子目录包含模型JSON和JavaScript文件。
- definitions- API 和产品定义 YAML 文件
2、创建应用
lb
他会问你一堆问题,自动创建目录及配置文件,然后,生成器将在构建应用程序时显示消息,包括:
- 初始化 项目文件夹结构。
- 创建默认 JSON 文件。
- 创建默认 JavaScript 文件。
- 下载和安装依赖的 Node 模块(就像你手动完成的一样 npm install)
3、创建数据源
lb datasource
4、创建模型
lb model
就是数据库表的映射及相应功能
创建完成会发现common->models目录下多了两个文件
XXXX.js
XXXX.json
json对应你的表结构,js对应你对外的restapi
5、扩展API,远程方法
注册远程方法有两种方式:
在代码中,在模型扩展文件 ( modelName.js) 中。
在 JSON 中,在模型定义 JSON 文件( modelName.json) 中。
假设您有一个 Person 模型,并且您想要添加一个 REST 端点,/greet该端点 返回带有请求中提供的名称的问候语。您将此代码添加到/common/models/person.js:
/common/models/person.js
module.exports = function(Person){
Person.greet = function(msg, cb) {
cb(null, 'Greetings... ' + msg);
}
Person.remoteMethod('greet', {
accepts: {arg: 'msg', type: 'string'},
returns: {arg: 'greeting', type: 'string'}
});
};
现在,例如,请求
POST /api/people/greet
有数据{“msg”: “John”}将返回:
Greetings... John!
更改路由
Person.remoteMethod('greet',{
accepts: {arg: 'msg', type: 'string'},
returns: {arg: 'greeting', type: 'string'},
http: {path: '/sayhi', verb: 'get'}
});
此调用将默认路由更改为
GET /api/people/sayhi
所以一个 GET 请求 http://localhost:3000/api/people/sayhi?msg=LoopBack%20developer 返回:
{"greeting": "Greetings... LoopBack developer"}
请注意上面的 REST API 请求使用复数形式“people”而不是“person”。LoopBack为 REST API 路由公开了 复数形式的模型名称。
英文原文:By default, the REST APIs are mounted to the plural of the model name; specifically:
Automatically-pluralized model name (the default). For example, if you have a location model, by default it is mounted to /locations.
说白了,路由自动以复数形式挂载到路由上,而不是手写方式一个一个声明
loopback很多东西默认继承于Express思想,所以还得往上追溯,否则搞不清楚
6、将 ACL 添加到远程方法
要限制对自定义远程方法的访问 ,请以与控制对任何模型 API 的访问相同的方式使用ACL 生成器。自定义远程方法的访问类型是执行
lb acl
7、远程hook挂钩
远程钩 使你之前或之后一个远程方法是由客户端调用以执行一个功能:
beforeRemote() 在远程方法之前运行。
afterRemote() 在远程方法成功完成后运行。
afterRemoteError() 在远程方法完成并出现错误后运行
modelName.beforeRemote( methodName, function( ctx, modelInstance, next) {
//...
next();
});
通配符
您可以在 中使用以下通配符methodName:
星号 ‘’ 匹配任何字符,直到第一次出现的分隔符’.’(句点)。
双星号匹配任何字符,包括分隔符 ‘.’ (句点)。
例如,用于 '.’ 匹配任何静态方法;用于 'prototype.’ 匹配任何实例方法。
以下示例在远程方法名称中使用通配符。每当执行名称以“save”结尾的任何远程方法时,都会调用此远程挂钩:
通用/模型/customer.js
Customer.beforeRemote('*.save', function(ctx, unused, next) {
if(ctx.req.accessToken) {
next();
} else {
next(new Error('must be logged in to update'))
}
});
Customer.afterRemote('*.save', function(ctx, user, next) {
console.log('user has been saved', user);
next();
});
8、Oauth2.0组件
LoopBack OAuth 2.0 组件具有以下关键元素:
授权服务器:在成功验证资源所有者并获得授权后,向客户端颁发访问令牌。该组件实现了 OAuth 2.0 协议端点,包括 授权端点 和 令牌端点。
资源服务器:托管受保护的资源,并能够使用访问令牌接受和响应受保护的资源请求。该组件提供中间件来保护 API 端点,以便仅接受具有有效 OAuth 2.0 访问令牌的请求。它还建立诸如客户端应用程序 ID 和用户 ID 之类的身份,以进行进一步的访问控制和个性化。
我们有专门的授权服务器,所以这里着重于资源服务器的使用
Third-party login using Passport
参考链接
该模块包括:
- UserIdentity 模型 - 跟踪第三方登录配置文件
- UserCredential 模型 -存储来自第三方提供商的凭据以表示用户的权限和授权
- ApplicationCredential 模型 - 存储与客户端应用程序关联的凭据
- PassportConfigurator - LoopBack 和 Passport 之间的桥梁
像往常一样为 Node 包安装第三方登录 (Passport) 组件:
$ npm install loopback-component-passport
官方提供的例子是google,twitter的,这个都有已经做好的module包支持,我们需要接入的是自己的单点登录认证,不适用,所以需要自己写
在server.js里加入如下代码:
var passport = require("passport");
var OAuth2Strategy = require("passport-oauth2").Strategy;
app.use(session({
resave: false,
saveUninitialized: true,
secret: "SECRET",
}));
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function(user, cb) {
cb(null, user);
});
passport.deserializeUser(function(obj, cb) {
cb(null, obj);
});
require("https").globalAgent.options.rejectUnauthorized = false;
passport.use(
new OAuth2Strategy(
{
authorizationURL: "https://xxxxxx/oauth2/authorize",
tokenURL: "https://xxxxxx/oauth2/token",
clientID: "48144",
clientSecret: "rQxxxxxxfiaNrS742xR3Q2pYqInyvK",
callbackURL: "http://localhost:3000/auth/oauth2/callback",
proxy: true,
},
function(accessToken, refreshToken, params, profile, cb) {
console.log(params); //一般是从profile里拿用户数据,但是这边可能是我们的单点登录没有使用profile的问题,造成数据拿不到,所以用params来拿
return cb(null, profile);
}
)
);
app.get("/auth/oauth2",
passport.authenticate("oauth2"));
app.get("/auth/oauth2/callback",
passport.authenticate("oauth2", { failureRedirect: "/" }),
function(req, res) {
res.send("Login efetuado com sucesso!");
}
);
运行后在界面能看到返回成功“Login efetuado com sucesso!”,在控制台能看到输出的所有用户参数,自己再获取切分。