Compare commits
4 Commits
661c189bf4
...
dev
Author | SHA1 | Date | |
---|---|---|---|
8fb899877b | |||
a21afc9719 | |||
18c2b5986b | |||
f06ca4b247 |
15
Dockerfile
Normal file
15
Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM alpine as build
|
||||
|
||||
ADD ./build/app /app
|
||||
|
||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories \
|
||||
&& apk --no-cache add ca-certificates
|
||||
|
||||
FROM scratch
|
||||
# copy the ca-certificate.crt from the build stage
|
||||
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
||||
COPY --from=build /app /app
|
||||
|
||||
EXPOSE 13721
|
||||
|
||||
ENTRYPOINT ["/app"]
|
9
Makefile
9
Makefile
@@ -1,7 +1,7 @@
|
||||
include .env
|
||||
include .env.local
|
||||
|
||||
.PHONY: proto
|
||||
.PHONY: build proto
|
||||
|
||||
run:
|
||||
go run cmd/mp-server/main.go \
|
||||
@@ -15,6 +15,13 @@ clean:
|
||||
|
||||
all: api
|
||||
|
||||
build:
|
||||
CGO_ENABLED=0 GOOS="linux" GOARCH="amd64" \
|
||||
go build -o ./build/app -ldflags="-s -w" -tags timetzdata ./cmd/mp-server
|
||||
upx build/app
|
||||
docker build -t esinio/weixin:mp-auth .
|
||||
rm build/app
|
||||
|
||||
docker.push:
|
||||
docker push esinio/weixin:oauth2
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import (
|
||||
)
|
||||
|
||||
type ClientCredential struct {
|
||||
request.Error
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int32 `json:"expires_in"`
|
||||
request.Error `gorm:"-"`
|
||||
AccessToken string `json:"access_token"`
|
||||
ExpiresIn int32 `json:"expires_in"`
|
||||
}
|
||||
|
@@ -5,10 +5,10 @@ import (
|
||||
)
|
||||
|
||||
type Token struct {
|
||||
request.Error
|
||||
AccessToken string `json:"access_token"` //获取到的凭证
|
||||
ExpiresIn int32 `json:"expires_in"` //凭证有效时间,单位:秒
|
||||
RefreshToken string `json:"refresh_token"` //有效期为30天,当失效之后,需要用户重新授
|
||||
OpenID string `json:"openid" gorm:"index"`
|
||||
Scope string `json:"scope"`
|
||||
request.Error `gorm:"-"`
|
||||
AccessToken string `json:"access_token"` //获取到的凭证
|
||||
ExpiresIn int32 `json:"expires_in"` //凭证有效时间,单位:秒
|
||||
RefreshToken string `json:"refresh_token"` //有效期为30天,当失效之后,需要用户重新授
|
||||
OpenID string `json:"openid" gorm:"index"`
|
||||
Scope string `json:"scope"`
|
||||
}
|
||||
|
@@ -5,14 +5,14 @@ import (
|
||||
)
|
||||
|
||||
type Userinfo struct {
|
||||
request.Error
|
||||
OpenID string `json:"openid" gorm:"index"`
|
||||
NickName string `json:"nickname"`
|
||||
Sex int32 `json:"sex"`
|
||||
Province string `json:"province"`
|
||||
City string `json:"city"`
|
||||
Country string `json:"country"`
|
||||
HeadImgURL string `json:"headimgurl"`
|
||||
Privilege []string `json:"privilege" gorm:"type:text[]"`
|
||||
UnionID string `json:"unionid"`
|
||||
request.Error `gorm:"-"`
|
||||
OpenID string `json:"openid" gorm:"index"`
|
||||
NickName string `json:"nickname"`
|
||||
Sex int32 `json:"sex"`
|
||||
Province string `json:"province"`
|
||||
City string `json:"city"`
|
||||
Country string `json:"country"`
|
||||
HeadImgURL string `json:"headimgurl"`
|
||||
Privilege []string `json:"privilege" gorm:"type:text[]"`
|
||||
UnionID string `json:"unionid"`
|
||||
}
|
||||
|
124
cmd/mp-auth-http/main.go
Normal file
124
cmd/mp-auth-http/main.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"net/http"
|
||||
|
||||
pb "git.esin.io/lab/weixin/protobuf/clientapi/mp/auth"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/protobuf/types/known/emptypb"
|
||||
)
|
||||
|
||||
var (
|
||||
lisPort string
|
||||
authServerEndpoint string
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.StringVar(&lisPort, "port", "3000", "server listen port")
|
||||
flag.StringVar(&authServerEndpoint, "auth.server", "localhost:13721", "auth grpc server endpoint")
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
if err := run(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func run() error {
|
||||
grpcDialOpts := []grpc.DialOption{
|
||||
grpc.WithInsecure(),
|
||||
grpc.WithBlock(),
|
||||
}
|
||||
grpcConn, err := grpc.Dial(authServerEndpoint, grpcDialOpts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h := NewHandler(pb.NewAuthServiceClient(grpcConn))
|
||||
|
||||
http.HandleFunc("/url", h.getCodeURL)
|
||||
http.HandleFunc("/token", h.exchangeToken)
|
||||
http.HandleFunc("/userinfo", h.getUserinfo)
|
||||
http.HandleFunc("/userinfo/sync", h.syncUserinfo)
|
||||
http.HandleFunc("/clientcredential", h.getClientCredential)
|
||||
|
||||
return http.ListenAndServe(":"+lisPort, nil)
|
||||
}
|
||||
|
||||
type restHandler struct {
|
||||
client pb.AuthServiceClient
|
||||
}
|
||||
|
||||
func NewHandler(client pb.AuthServiceClient) *restHandler {
|
||||
return &restHandler{
|
||||
client: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (h restHandler) getCodeURL(w http.ResponseWriter, r *http.Request) {
|
||||
resp, err := h.client.GetCodeURL(r.Context(), &pb.GetCodeURLRequest{
|
||||
RedirectUrl: r.FormValue("redirect_url"),
|
||||
State: r.FormValue("state"),
|
||||
Scope: pb.GetCodeURLRequest_snsapi_base,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
encoder := json.NewEncoder(w)
|
||||
encoder.SetEscapeHTML(false)
|
||||
encoder.Encode(resp)
|
||||
}
|
||||
|
||||
func (h restHandler) exchangeToken(w http.ResponseWriter, r *http.Request) {
|
||||
code := r.FormValue("code")
|
||||
|
||||
resp, err := h.client.ExchangeToken(r.Context(), &pb.ExchangeTokenRequest{
|
||||
Code: code,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
|
||||
func (h restHandler) getUserinfo(w http.ResponseWriter, r *http.Request) {
|
||||
openid := r.FormValue("openid")
|
||||
resp, err := h.client.GetUserinfo(r.Context(), &pb.GetUserinfoRequest{
|
||||
OpenId: openid,
|
||||
Lang: pb.GetUserinfoRequest_zh_CN,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
|
||||
func (h restHandler) syncUserinfo(w http.ResponseWriter, r *http.Request) {
|
||||
openid := r.FormValue("openid")
|
||||
resp, err := h.client.SyncUserinfo(r.Context(), &pb.SyncUserinfoRequest{
|
||||
OpenId: openid,
|
||||
Lang: pb.SyncUserinfoRequest_zh_CN,
|
||||
})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}
|
||||
|
||||
func (h restHandler) getClientCredential(w http.ResponseWriter, r *http.Request) {
|
||||
resp, err := h.client.GetClientCredential(r.Context(), &emptypb.Empty{})
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
json.NewEncoder(w).Encode(resp)
|
||||
}
|
19
db.sql
Normal file
19
db.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
create schema "identity"
|
||||
create table if not exists "user" (
|
||||
id text primary key,
|
||||
openid text unique not null,
|
||||
created_at timestamp with time zone default current_timestamp,
|
||||
updated_at timestamp with time zone default current_timestamp
|
||||
)
|
||||
create table if not exists "user_token" (
|
||||
user_id text primary key,
|
||||
access_token text,
|
||||
expires_in smallint,
|
||||
refresh_token text,
|
||||
scope text
|
||||
)
|
||||
create table if not exists "user_userinfo" (
|
||||
user_id text primary key,
|
||||
nickname text,
|
||||
head_img_url text
|
||||
)
|
@@ -53,7 +53,7 @@ func (srv Service) PublishEvent(ctx context.Context, subject string, message int
|
||||
return nil
|
||||
}
|
||||
|
||||
func (srv Service) GetAuthCodeURL(ctx context.Context, req *pb.GetCodeURLRequest) (*pb.GetCodeURLResponse, error) {
|
||||
func (srv Service) GetCodeURL(ctx context.Context, req *pb.GetCodeURLRequest) (*pb.GetCodeURLResponse, error) {
|
||||
resp := srv.client.GetCodeURL(req.RedirectUrl, req.State, mpauth.Scope(req.Scope.String()))
|
||||
|
||||
return &pb.GetCodeURLResponse{
|
||||
@@ -163,7 +163,7 @@ func (srv Service) SyncUserinfo(ctx context.Context, req *pb.SyncUserinfoRequest
|
||||
return nil, status.Errorf(codes.Internal, errors.Wrap(err, "get userinfo token from weixin failed").Error())
|
||||
}
|
||||
|
||||
userinfo = Userinfo{Userinfo: *resp}
|
||||
userinfo.Userinfo = *resp
|
||||
if err := srv.db.Save(&userinfo).Error; err != nil {
|
||||
return nil, status.Errorf(codes.Internal, errors.Wrap(err, "sync userinfo and save to database failed").Error())
|
||||
}
|
||||
|
Reference in New Issue
Block a user