Compare commits
	
		
			2 Commits
		
	
	
		
			dev
			...
			661c189bf4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 661c189bf4 | |||
| 64b33915da | 
							
								
								
									
										15
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,15 +0,0 @@
 | 
				
			|||||||
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
 | 
				
			||||||
include .env.local
 | 
					include .env.local
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.PHONY: build proto 
 | 
					.PHONY: proto 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
run:
 | 
					run:
 | 
				
			||||||
	go run cmd/mp-server/main.go \
 | 
						go run cmd/mp-server/main.go \
 | 
				
			||||||
@@ -15,13 +15,6 @@ clean:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
all: api
 | 
					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:
 | 
				
			||||||
	docker push esinio/weixin:oauth2
 | 
						docker push esinio/weixin:oauth2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ClientCredential struct {
 | 
					type ClientCredential struct {
 | 
				
			||||||
	request.Error `gorm:"-"`
 | 
						request.Error
 | 
				
			||||||
	AccessToken   string `json:"access_token"`
 | 
						AccessToken string `json:"access_token"`
 | 
				
			||||||
	ExpiresIn     int32  `json:"expires_in"`
 | 
						ExpiresIn   int32  `json:"expires_in"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,10 +5,10 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Token struct {
 | 
					type Token struct {
 | 
				
			||||||
	request.Error `gorm:"-"`
 | 
						request.Error
 | 
				
			||||||
	AccessToken   string `json:"access_token"`  //获取到的凭证
 | 
						AccessToken  string `json:"access_token"`  //获取到的凭证
 | 
				
			||||||
	ExpiresIn     int32  `json:"expires_in"`    //凭证有效时间,单位:秒
 | 
						ExpiresIn    int32  `json:"expires_in"`    //凭证有效时间,单位:秒
 | 
				
			||||||
	RefreshToken  string `json:"refresh_token"` //有效期为30天,当失效之后,需要用户重新授
 | 
						RefreshToken string `json:"refresh_token"` //有效期为30天,当失效之后,需要用户重新授
 | 
				
			||||||
	OpenID        string `json:"openid"  gorm:"index"`
 | 
						OpenID       string `json:"openid"  gorm:"index"`
 | 
				
			||||||
	Scope         string `json:"scope"`
 | 
						Scope        string `json:"scope"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,14 +5,14 @@ import (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Userinfo struct {
 | 
					type Userinfo struct {
 | 
				
			||||||
	request.Error `gorm:"-"`
 | 
						request.Error
 | 
				
			||||||
	OpenID        string   `json:"openid" gorm:"index"`
 | 
						OpenID     string   `json:"openid" gorm:"index"`
 | 
				
			||||||
	NickName      string   `json:"nickname"`
 | 
						NickName   string   `json:"nickname"`
 | 
				
			||||||
	Sex           int32    `json:"sex"`
 | 
						Sex        int32    `json:"sex"`
 | 
				
			||||||
	Province      string   `json:"province"`
 | 
						Province   string   `json:"province"`
 | 
				
			||||||
	City          string   `json:"city"`
 | 
						City       string   `json:"city"`
 | 
				
			||||||
	Country       string   `json:"country"`
 | 
						Country    string   `json:"country"`
 | 
				
			||||||
	HeadImgURL    string   `json:"headimgurl"`
 | 
						HeadImgURL string   `json:"headimgurl"`
 | 
				
			||||||
	Privilege     []string `json:"privilege" gorm:"type:text[]"`
 | 
						Privilege  []string `json:"privilege" gorm:"type:text[]"`
 | 
				
			||||||
	UnionID       string   `json:"unionid"`
 | 
						UnionID    string   `json:"unionid"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,124 +0,0 @@
 | 
				
			|||||||
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
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								db.sql
									
									
									
									
									
								
							@@ -1,19 +0,0 @@
 | 
				
			|||||||
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
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (srv Service) GetCodeURL(ctx context.Context, req *pb.GetCodeURLRequest) (*pb.GetCodeURLResponse, error) {
 | 
					func (srv Service) GetAuthCodeURL(ctx context.Context, req *pb.GetCodeURLRequest) (*pb.GetCodeURLResponse, error) {
 | 
				
			||||||
	resp := srv.client.GetCodeURL(req.RedirectUrl, req.State, mpauth.Scope(req.Scope.String()))
 | 
						resp := srv.client.GetCodeURL(req.RedirectUrl, req.State, mpauth.Scope(req.Scope.String()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &pb.GetCodeURLResponse{
 | 
						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())
 | 
							return nil, status.Errorf(codes.Internal, errors.Wrap(err, "get userinfo token from weixin failed").Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	userinfo.Userinfo = *resp
 | 
						userinfo = Userinfo{Userinfo: *resp}
 | 
				
			||||||
	if err := srv.db.Save(&userinfo).Error; err != nil {
 | 
						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())
 | 
							return nil, status.Errorf(codes.Internal, errors.Wrap(err, "sync userinfo and save to database failed").Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user