1.nginx
nginx-1.13.8.zip
http://nginx.org/en/download.html
unzip to E:\web-server-for-win
E:\web-server-for-win\nginx-1.13.8\conf
nginx配置修改
nginx.conf
红色字体为新添加配置
######## start ########
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
# upstream for golang service,0.0.0.0:8000
upstream api_server_01.localtion01 {
server localhost:8000;
}
server {
listen 80;
server_name localhost;
# all dir or files that angular build(ng build --prod) in dist path
root E:\pgmon-web\dist;
# SPA index setting
index index.html index.htm;
#charset koi8-r;
#access_log logs/host.access.log main;
# local service(angular SPA app, 0.0.0.0:80)
location / {
try_files $uri $uri/ =404;
}
# golang api service , api_server_01.localtion01
# CORS(跨域访问) and proxy(代理) access
# return same in browser: "localhost/api/status"
# or "localhost:8000/api/status"
location /api/{
rewrite ^(api/?.*)$ /$1 break;
proxy_pass http://api_server_01.localtion01;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Cookie $http_cookie;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers Content-Type;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
add_header Access-Control-Allow-Credentials true;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
}
######## end ########
检查配置命令行
e:\web-server-for-win\nginx-1.13.8>nginx -t
nginx: the configuration file e:\web-server-for-win\nginx-1.13.8/conf/nginx.conf syntax is ok
nginx: configuration file e:\web-server-for-win\nginx-1.13.8/conf/nginx.conf test is successful
启动nginx程序
e:\web-server-for-win\nginx-1.13.8>nginx.exe
2.angular 5
1). install nodejs
node-v8.9.3-x64.msi
2).setting prog
由于 npm 官网镜像国内访问太慢,这里我使用了淘宝的npm镜像,安装方法如下:
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
执行后我们就可以使用 cnpm 命令来安装模块:
$ npm install -g @angular/cli@latest
项目初始化
新建项目
E:\>ng new pgmon-web --routing
选项:
--routing,附加路由功能
E:\>cd pgmon-web
新建组件(默认每个组件单独生成文件夹)
E:\pgmon-web>ng g c login
E:\pgmon-web>ng g c dashboard
新建服务(每个服务单独生成生成文件夹)
E:\pgmon-web> ng g s --flat false AuthGuard
create src/app/auth-guard/auth-guard.service.spec.ts (393 bytes)
create src/app/auth-guard/auth-guard.service.ts (115 bytes)
E:\pgmon-web> ng g s --flat false AuthenticationService
create src/app/authentication-service/authentication-service.service.spec.ts (465 bytes)
create src/app/authentication-service/authentication-service.service.ts (127 bytes)
E:\pgmon-web> ng g s --flat false UserService
create src/app/user-service/user-service.service.spec.ts (405 bytes)
create src/app/user-service/user-service.service.ts (117 bytes)
E:\pgmon-web>
安装node模块
E:\pgmon-web> npm install bootstrap@next
选项:
@next,使用最新版本4.0.0-beta.2,否则使用版本3
npm WARN bootstrap@4.0.0-beta.2 requires a peer of jquery@1.9.1 - 3 but none is installed. You must install peer dependencies yourself.
npm WARN bootstrap@4.0.0-beta.2 requires a peer of popper.js@^1.12.3 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.1.3 (node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.1.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
+ bootstrap@4.0.0-beta.2
added 115 packages, removed 5 packages and updated 2 packages in 23.201s
E:\pgmon-web>
加载bootstrap到angular组件
E:\pgmon-web>目录,编辑.angular-cli.json文件
"styles": [
"styles.css",
"../node_modules/bootstrap/dist/css/bootstrap.css"
],
生成生产环境部署文件,E:\pgmon-web\dist
E:\pgmon-web>ng build --prod
3.golang
软件列表:
go1.9.windows-amd64.msi
Git-2.14.1-32-bit.exe
Sublime Text Build 3143 x64 Setup.exe
进入命令行
Microsoft Windows [版本 10.0.14393]
(c) 2016 Microsoft Corporation。保留所有权利。
C:\Users\Administrator>e:
E:\>
create project
E:\>mkdir go-web
E:\>cd go-web
init project
E:\go-web>mkdir pkg
E:\go-web>mkdir src
E:\go-web>mkdir bin
create app
E:\go-web>cd src
E:\go-web\src>mkdir app
E:\go-web\src>cd app
install dep(golang packages admin tools)
E:\go-web\src\app>set GOPATH=E:\go-web
E:\go-web\src\app>go get -u github.com/golang/dep/cmd/dep
init dep
E:\go-web\src\app>e:\go-web\bin\dep init
E:\go-web\src\app>e:\go-web\bin\dep help
Dep is a tool for managing dependencies for Go projects
Usage: "dep [command]"
Commands:
init Initialize a new project with manifest and lock files
status Report the status of the project's dependencies
ensure Ensure a dependency is safely vendored in the project
prune Prune the vendor tree of unused packages
version Show the dep version information
Examples:
dep init set up a new project
dep ensure install the project's dependencies
dep ensure -update update the locked versions of all dependencies
dep ensure -add github.com/pkg/errors add a dependency to the project
Use "dep help [command]" for more information about a command.
E:\go-web\src\app>
E:\go-web\src\app>e:\go-web\bin\dep status
PROJECT CONSTRAINT VERSION REVISION LATEST PKGS USED
E:\go-web\src\app>
编辑项目
相关main.go,放入目录E:\go-web\src\app>
######### code start #############
package main
// import golang packages
import (
"encoding/json"
"fmt"
"log"
"net/http"
"strings"
"time"
"github.com/codegangsta/negroni"
"github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go/request"
)
// def: SecretKey
const (
SecretKey = "welcome to wangshubo's blog"
)
// func: fatal error
func fatal(err error) {
if err != nil {
log.Fatal(err)
}
}
// def: UserCredentials, User, Response, Token
type UserCredentials struct {
Username string `json:"username"`
Password string `json:"password"`
}
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Username string `json:"username"`
Password string `json:"password"`
}
type Response struct {
Data string `json:"data"`
}
type Token struct {
Token string `json:"token"`
}
// func: start server
func StartServer() {
http.HandleFunc("/api/status", ServerStatusHandler)
http.HandleFunc("/api/authenticate", AuthHandler)
http.Handle("/resource", negroni.New(
negroni.HandlerFunc(ValidateTokenMiddleware),
negroni.Wrap(http.HandlerFunc(ProtectedHandler)),
))
log.Println("Now listening...")
http.ListenAndServe(":8000", nil)
}
// def: main
func main() {
// start server
StartServer()
}
// func: test url
func ServerStatusHandler(w http.ResponseWriter, r *http.Request) {
response := Response{"Golang API Server run successfull."}
JsonResponse(response, w)
}
// func: print message of gained access
func ProtectedHandler(w http.ResponseWriter, r *http.Request) {
response := Response{"Gained access to protected resource"}
JsonResponse(response, w)
}
// func: auth for username and password
func AuthHandler(w http.ResponseWriter, r *http.Request) {
var user UserCredentials
err := json.NewDecoder(r.Body).Decode(&user)
if err != nil {
w.WriteHeader(http.StatusForbidden)
fmt.Fprint(w, "Error in request")
return
}
// def: access database, get user
if strings.ToLower(user.Username) != "admin" {
if user.Password != "123456" {
w.WriteHeader(http.StatusForbidden)
fmt.Println("Error logging in")
fmt.Fprint(w, "Invalid credentials")
return
}
}
// generate token with claims map
token := jwt.New(jwt.SigningMethodHS256)
claims := make(jwt.MapClaims)
claims["exp"] = time.Now().Add(time.Hour * time.Duration(1)).Unix()
claims["iat"] = time.Now().Unix()
token.Claims = claims
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(w, "Error extracting the key")
fatal(err)
}
// token singed
tokenString, err := token.SignedString([]byte(SecretKey))
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprintln(w, "Error while signing the token")
fatal(err)
}
// return response
response := Token{tokenString}
JsonResponse(response, w)
}
// func: validate token
func ValidateTokenMiddleware(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
token, err := request.ParseFromRequest(r, request.AuthorizationHeaderExtractor,
func(token *jwt.Token) (interface{}, error) {
return []byte(SecretKey), nil
})
if err == nil {
if token.Valid {
next(w, r)
} else {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprint(w, "Token is not valid")
}
} else {
w.WriteHeader(http.StatusUnauthorized)
fmt.Fprint(w, "Unauthorized access to this resource")
}
}
// func: return json format's response
func JsonResponse(response interface{}, w http.ResponseWriter) {
json, err := json.Marshal(response)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
w.Write(json)
}
######### code end #############
安装项目依赖包(安装前必须先进行dep初始化)
E:\go-web\src\app> e:\go-web\bin\dep ensure
运行项目
E:\go-web\src\app> go run main.go
打开浏览器,
输入"localhost/api/status"
或者"localhost:8000/api/status"
browser output:
{"data":"Golang API Server run successfull."}