commit
8dfd76084d
51 changed files with 976 additions and 0 deletions
@ -0,0 +1,8 @@ |
||||
# 默认忽略的文件 |
||||
/shelf/ |
||||
/workspace.xml |
||||
# 基于编辑器的 HTTP 客户端请求 |
||||
/httpRequests/ |
||||
# Datasource local storage ignored files |
||||
/dataSources/ |
||||
/dataSources.local.xml |
@ -0,0 +1,26 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="CompilerConfiguration"> |
||||
<annotationProcessing> |
||||
<profile default="true" name="Default" enabled="true" /> |
||||
<profile name="Maven default annotation processors profile" enabled="true"> |
||||
<sourceOutputDir name="target/generated-sources/annotations" /> |
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> |
||||
<outputRelativeToContentRoot value="true" /> |
||||
<module name="sso-cart" /> |
||||
<module name="sso-vip" /> |
||||
<module name="sso-login" /> |
||||
<module name="sso-main" /> |
||||
</profile> |
||||
</annotationProcessing> |
||||
</component> |
||||
<component name="JavacSettings"> |
||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE"> |
||||
<module name="sso-cart" options="-parameters" /> |
||||
<module name="sso-login" options="-parameters" /> |
||||
<module name="sso-main" options="-parameters" /> |
||||
<module name="sso-vip" options="-parameters" /> |
||||
<module name="use-cookie-sso" options="" /> |
||||
</option> |
||||
</component> |
||||
</project> |
@ -0,0 +1,11 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="Encoding"> |
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" /> |
||||
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" /> |
||||
<file url="file://$PROJECT_DIR$/sso-cart/src/main/java" charset="UTF-8" /> |
||||
<file url="file://$PROJECT_DIR$/sso-login/src/main/java" charset="UTF-8" /> |
||||
<file url="file://$PROJECT_DIR$/sso-main/src/main/java" charset="UTF-8" /> |
||||
<file url="file://$PROJECT_DIR$/sso-vip/src/main/java" charset="UTF-8" /> |
||||
</component> |
||||
</project> |
@ -0,0 +1,8 @@ |
||||
<component name="InspectionProjectProfileManager"> |
||||
<profile version="1.0"> |
||||
<option name="myName" value="Project Default" /> |
||||
<inspection_tool class="JavadocDeclaration" enabled="true" level="WARNING" enabled_by_default="true"> |
||||
<option name="ADDITIONAL_TAGS" value="author:,description:,date:" /> |
||||
</inspection_tool> |
||||
</profile> |
||||
</component> |
@ -0,0 +1,20 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="RemoteRepositoriesConfiguration"> |
||||
<remote-repository> |
||||
<option name="id" value="central" /> |
||||
<option name="name" value="Maven Central repository" /> |
||||
<option name="url" value="https://repo1.maven.org/maven2" /> |
||||
</remote-repository> |
||||
<remote-repository> |
||||
<option name="id" value="jboss.community" /> |
||||
<option name="name" value="JBoss Community repository" /> |
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" /> |
||||
</remote-repository> |
||||
<remote-repository> |
||||
<option name="id" value="central" /> |
||||
<option name="name" value="Central Repository" /> |
||||
<option name="url" value="https://maven.aliyun.com/repository/public" /> |
||||
</remote-repository> |
||||
</component> |
||||
</project> |
@ -0,0 +1,14 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="ExternalStorageConfigurationManager" enabled="true" /> |
||||
<component name="MavenProjectsManager"> |
||||
<option name="originalFiles"> |
||||
<list> |
||||
<option value="$PROJECT_DIR$/pom.xml" /> |
||||
</list> |
||||
</option> |
||||
</component> |
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="corretto-1.8" project-jdk-type="JavaSDK"> |
||||
<output url="file://$PROJECT_DIR$/out" /> |
||||
</component> |
||||
</project> |
@ -0,0 +1,124 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project version="4"> |
||||
<component name="Palette2"> |
||||
<group name="Swing"> |
||||
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" /> |
||||
</item> |
||||
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" /> |
||||
</item> |
||||
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" /> |
||||
</item> |
||||
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true"> |
||||
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" /> |
||||
</item> |
||||
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" /> |
||||
<initial-values> |
||||
<property name="text" value="Button" /> |
||||
</initial-values> |
||||
</item> |
||||
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> |
||||
<initial-values> |
||||
<property name="text" value="RadioButton" /> |
||||
</initial-values> |
||||
</item> |
||||
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" /> |
||||
<initial-values> |
||||
<property name="text" value="CheckBox" /> |
||||
</initial-values> |
||||
</item> |
||||
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" /> |
||||
<initial-values> |
||||
<property name="text" value="Label" /> |
||||
</initial-values> |
||||
</item> |
||||
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> |
||||
<preferred-size width="150" height="-1" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> |
||||
<preferred-size width="150" height="-1" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1"> |
||||
<preferred-size width="150" height="-1" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||
<preferred-size width="150" height="50" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||
<preferred-size width="150" height="50" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||
<preferred-size width="150" height="50" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" /> |
||||
</item> |
||||
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||
<preferred-size width="150" height="50" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3"> |
||||
<preferred-size width="150" height="50" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3"> |
||||
<preferred-size width="150" height="50" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> |
||||
<preferred-size width="200" height="200" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3"> |
||||
<preferred-size width="200" height="200" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true"> |
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> |
||||
</item> |
||||
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" /> |
||||
</item> |
||||
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" /> |
||||
</item> |
||||
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" /> |
||||
</item> |
||||
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1"> |
||||
<preferred-size width="-1" height="20" /> |
||||
</default-constraints> |
||||
</item> |
||||
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false"> |
||||
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" /> |
||||
</item> |
||||
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false"> |
||||
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" /> |
||||
</item> |
||||
</group> |
||||
</component> |
||||
</project> |
@ -0,0 +1,41 @@ |
||||
### 基于SpringBoot+Thymeleaf+maven实现基于Cookie的单点登录 |
||||
|
||||
#### 使用依赖 |
||||
|
||||
```xml |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-web</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.projectlombok</groupId> |
||||
<artifactId>lombok</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId> |
||||
</dependency> |
||||
``` |
||||
|
||||
#### 四个模块 |
||||
|
||||
- `sso-main`: 首页 |
||||
- `sso-login`: 登录 |
||||
- `sso-cart`: 购物车 |
||||
- `sso-vip`: `vip`系统 |
||||
|
||||
#### 接口 |
||||
|
||||
| 接口类型 | 接口地址 | |
||||
| --------- | -------------------------------------------- | |
||||
| 首页 | `http://www.codeshop.com:8082/view/index` | |
||||
| 登录 | `http://login.codeshop.com:8081/view/login` | |
||||
| 登出 | `http://login.codeshop.com:8081/view/logout` | |
||||
| 购物车 | `http://cart.codeshop.com:8080/view/index` | |
||||
| `vip`系统 | `http://vip.codeshop.com:8083/view/index` | |
||||
|
||||
#### 单点登录 |
||||
|
||||
三个服务: 首页、购物车、`vip`系统,有一个成功登录,则所有服务均成功登录,一个退出登录,所有的服务均需重新登录 |
@ -0,0 +1,57 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<groupId>cc.bnblogs</groupId> |
||||
<artifactId>use-cookie-sso</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
<packaging>pom</packaging> |
||||
<modules> |
||||
<module>sso-main</module> |
||||
<module>sso-cart</module> |
||||
<module>sso-vip</module> |
||||
<module>sso-login</module> |
||||
</modules> |
||||
|
||||
<parent> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-parent</artifactId> |
||||
<relativePath/> |
||||
<version>2.7.9</version> |
||||
</parent> |
||||
|
||||
<properties> |
||||
<maven.compiler.source>8</maven.compiler.source> |
||||
<maven.compiler.target>8</maven.compiler.target> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
</properties> |
||||
|
||||
<dependencies> |
||||
|
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-web</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-devtools</artifactId> |
||||
<scope>runtime</scope> |
||||
<optional>true</optional> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.projectlombok</groupId> |
||||
<artifactId>lombok</artifactId> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId> |
||||
</dependency> |
||||
|
||||
</dependencies> |
||||
|
||||
</project> |
@ -0,0 +1,20 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<parent> |
||||
<groupId>cc.bnblogs</groupId> |
||||
<artifactId>use-cookie-sso</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
|
||||
<artifactId>sso-cart</artifactId> |
||||
|
||||
<properties> |
||||
<maven.compiler.source>8</maven.compiler.source> |
||||
<maven.compiler.target>8</maven.compiler.target> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
</properties> |
||||
|
||||
</project> |
@ -0,0 +1,23 @@ |
||||
package cc.bnblogs; |
||||
|
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.web.client.RestTemplate; |
||||
|
||||
/** |
||||
* @description: 购物车子模块 |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 15:37 |
||||
*/ |
||||
@SpringBootApplication |
||||
public class CartApplication { |
||||
public static void main(String[] args) { |
||||
SpringApplication.run(CartApplication.class,args); |
||||
} |
||||
|
||||
@Bean |
||||
public RestTemplate restTemplate() { |
||||
return new RestTemplate(); |
||||
} |
||||
} |
@ -0,0 +1,43 @@ |
||||
package cc.bnblogs.controller; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Controller; |
||||
import org.springframework.web.bind.annotation.CookieValue; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.client.RestTemplate; |
||||
import org.thymeleaf.util.StringUtils; |
||||
|
||||
import javax.servlet.http.Cookie; |
||||
import javax.servlet.http.HttpSession; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @description: 购物车页面 |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 16:16 |
||||
*/ |
||||
@Controller |
||||
@RequestMapping("/view") |
||||
public class ViewController { |
||||
@Autowired |
||||
private RestTemplate restTemplate; |
||||
|
||||
private final String LOGIN_INFO_ADDR = "http://login.codeshop.com:8081/login/info?token="; |
||||
|
||||
@GetMapping("/index") |
||||
public String toIndex(@CookieValue(required = false,value = "TOKEN")Cookie cookie, |
||||
HttpSession httpSession) { |
||||
if (cookie!=null) { |
||||
String token = cookie.getValue(); |
||||
if(!StringUtils.isEmpty(token)) { |
||||
// 访问/login/info接口时带上token请求登录用户信息
|
||||
Map result = restTemplate.getForObject(LOGIN_INFO_ADDR + token, Map.class); |
||||
// 打印已登录用户信息
|
||||
// System.out.println(result);
|
||||
httpSession.setAttribute("loginUser",result); |
||||
} |
||||
} |
||||
return "index"; |
||||
} |
||||
} |
@ -0,0 +1,2 @@ |
||||
server: |
||||
port: 8080 |
@ -0,0 +1,18 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>购物车</title> |
||||
</head> |
||||
<body> |
||||
<h1>这里是购物车</h1> |
||||
<p th:unless="${session.loginUser==null}"> |
||||
<span style="color: deepskyblue;" th:text="${session.loginUser.username}"></span> 已登录 |
||||
</p> |
||||
|
||||
<span> |
||||
<a th:if="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/login?target=http://cart.codeshop.com:8080/view/index">登录</a> |
||||
<a th:unless="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/logout?target=http://cart.codeshop.com:8080/view/index">退出</a> |
||||
</span> |
||||
</body> |
||||
</html> |
@ -0,0 +1,2 @@ |
||||
server: |
||||
port: 8080 |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,18 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>购物车</title> |
||||
</head> |
||||
<body> |
||||
<h1>这里是购物车</h1> |
||||
<p th:unless="${session.loginUser==null}"> |
||||
<span style="color: deepskyblue;" th:text="${session.loginUser.username}"></span> 已登录 |
||||
</p> |
||||
|
||||
<span> |
||||
<a th:if="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/login?target=http://cart.codeshop.com:8080/view/index">登录</a> |
||||
<a th:unless="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/logout?target=http://cart.codeshop.com:8080/view/index">退出</a> |
||||
</span> |
||||
</body> |
||||
</html> |
@ -0,0 +1,20 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<parent> |
||||
<groupId>cc.bnblogs</groupId> |
||||
<artifactId>use-cookie-sso</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
|
||||
<artifactId>sso-login</artifactId> |
||||
|
||||
<properties> |
||||
<maven.compiler.source>8</maven.compiler.source> |
||||
<maven.compiler.target>8</maven.compiler.target> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
</properties> |
||||
|
||||
</project> |
@ -0,0 +1,23 @@ |
||||
package cc.bnblogs; |
||||
|
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.web.client.RestTemplate; |
||||
|
||||
/** |
||||
* @description: 登录子模块 |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 15:38 |
||||
*/ |
||||
@SpringBootApplication |
||||
public class LoginApplication { |
||||
public static void main(String[] args) { |
||||
SpringApplication.run(LoginApplication.class,args); |
||||
} |
||||
|
||||
@Bean |
||||
public RestTemplate restTemplate() { |
||||
return new RestTemplate(); |
||||
} |
||||
} |
@ -0,0 +1,83 @@ |
||||
package cc.bnblogs.controller; |
||||
|
||||
import cc.bnblogs.pojo.User; |
||||
import cc.bnblogs.utils.LoginCacheUtils; |
||||
import org.springframework.http.HttpStatus; |
||||
import org.springframework.http.ResponseEntity; |
||||
import org.springframework.stereotype.Controller; |
||||
import org.springframework.web.bind.annotation.*; |
||||
import org.thymeleaf.util.StringUtils; |
||||
|
||||
import javax.servlet.http.Cookie; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.servlet.http.HttpSession; |
||||
import java.util.*; |
||||
|
||||
/** |
||||
* @description: 用户登录逻辑 |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 15:53 |
||||
*/ |
||||
@Controller |
||||
@RequestMapping("/login") |
||||
public class LoginController { |
||||
|
||||
// 模拟用户数据
|
||||
private static Set<User> dbUsers; |
||||
|
||||
static { |
||||
dbUsers = new HashSet<>(); |
||||
dbUsers.add(new User(1,"user1","123456")); |
||||
dbUsers.add(new User(2,"user2","123456")); |
||||
dbUsers.add(new User(3,"user3","123456")); |
||||
dbUsers.add(new User(4,"user4","123456")); |
||||
dbUsers.add(new User(5,"user5","123456")); |
||||
dbUsers.add(new User(6,"user6","123456")); |
||||
} |
||||
@PostMapping |
||||
public String doLogin(User user, HttpSession httpSession, HttpServletResponse httpServletResponse) { |
||||
String target = (String) httpSession.getAttribute("target"); |
||||
|
||||
// 模拟数据库根据用户名和密码查询该用户是否存在
|
||||
Optional<User> first = dbUsers.stream().filter(dbUser -> dbUser.getUsername().equals(user.getUsername()) && |
||||
dbUser.getPassword().equals(user.getPassword())).findFirst(); |
||||
|
||||
// 如果该用户存在
|
||||
if (first.isPresent()) { |
||||
// 保存用户登录信息
|
||||
// 生成一个token作为key
|
||||
String token = UUID.randomUUID().toString(); |
||||
// 将token存入cookie
|
||||
Cookie cookie = new Cookie("TOKEN",token); |
||||
// 设置相同的域
|
||||
cookie.setDomain("codeshop.com"); |
||||
// 将cookie通过响应返回
|
||||
httpServletResponse.addCookie(cookie); |
||||
|
||||
LoginCacheUtils.loginUser.put(token,first.get()); |
||||
} |
||||
else { |
||||
// 返回登录失败界面,可选择重新登录
|
||||
httpSession.setAttribute("msg","用户名或密码错误"); |
||||
return "login"; |
||||
} |
||||
// 重定向到登录前的地址
|
||||
return "redirect:" + target; |
||||
} |
||||
|
||||
/** |
||||
* 根据请求中的token决定是否返回用户数据 |
||||
* @param token 请求方提供访问数据的token |
||||
* @return 返回响应结果 |
||||
*/ |
||||
@GetMapping("info") |
||||
@ResponseBody |
||||
public ResponseEntity<User> getUserInfo(String token) { |
||||
if (!StringUtils.isEmpty(token)) { |
||||
User user = LoginCacheUtils.loginUser.get(token); |
||||
return ResponseEntity.ok(user); |
||||
} else { |
||||
return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,59 @@ |
||||
package cc.bnblogs.controller; |
||||
|
||||
import cc.bnblogs.pojo.User; |
||||
import cc.bnblogs.utils.LoginCacheUtils; |
||||
import org.springframework.stereotype.Controller; |
||||
import org.springframework.web.bind.annotation.CookieValue; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
import org.thymeleaf.util.StringUtils; |
||||
|
||||
import javax.servlet.http.Cookie; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import javax.servlet.http.HttpSession; |
||||
|
||||
/** |
||||
* @description: 页面跳转逻辑 |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 15:55 |
||||
*/ |
||||
@Controller |
||||
@RequestMapping("/view") |
||||
|
||||
public class ViewController { |
||||
@GetMapping("/login") |
||||
public String toLogin(@RequestParam(required = false,defaultValue = "") String target, |
||||
HttpSession httpSession, |
||||
@CookieValue(required = false, value = "TOKEN") Cookie cookie) { |
||||
if (StringUtils.isEmpty(target)) { |
||||
target = "http://www.codeshop.com:8082/view/index/"; |
||||
} |
||||
|
||||
// 如果用户已经成功登录,则不需要重复登录,直接重定向到页面
|
||||
// 从token中获取到用户信息
|
||||
if (cookie!=null) { |
||||
String token = cookie.getValue(); |
||||
User user = LoginCacheUtils.loginUser.get(token); |
||||
if (user != null) { |
||||
return "redirect:" + target; |
||||
} |
||||
} |
||||
|
||||
// todo: 注意这里没有做地址校验
|
||||
httpSession.setAttribute("target",target); |
||||
return "login"; |
||||
} |
||||
|
||||
/** |
||||
*退出账户,将cookie设置为已过期 |
||||
*删除已登录的用户 |
||||
*/ |
||||
@GetMapping("/logout") |
||||
public String loginOut(@CookieValue(value = "TOKEN") Cookie cookie, HttpServletResponse response, String target) { |
||||
cookie.setMaxAge(0); |
||||
LoginCacheUtils.loginUser.remove(cookie.getValue()); |
||||
response.addCookie(cookie); |
||||
return "redirect:" + target; |
||||
} |
||||
} |
@ -0,0 +1,23 @@ |
||||
package cc.bnblogs.pojo; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
import lombok.experimental.Accessors; |
||||
|
||||
/** |
||||
* @description: 用户实体 |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 15:51 |
||||
*/ |
||||
@Data |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
// 使用链式调用
|
||||
@Accessors(chain = true) |
||||
public class User { |
||||
private Integer id; |
||||
private String username; |
||||
private String password; |
||||
|
||||
} |
@ -0,0 +1,15 @@ |
||||
package cc.bnblogs.utils; |
||||
|
||||
import cc.bnblogs.pojo.User; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @description: |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 17:42 |
||||
*/ |
||||
public class LoginCacheUtils { |
||||
public static Map<String, User> loginUser = new HashMap<>(); |
||||
} |
@ -0,0 +1,2 @@ |
||||
server: |
||||
port: 8081 |
@ -0,0 +1,23 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>登录页</title> |
||||
<style> |
||||
button { |
||||
margin-left: 5px; |
||||
} |
||||
</style> |
||||
|
||||
</head> |
||||
<body> |
||||
<h2>欢迎来到登录页面</h2> |
||||
<form action="/login" method="post"> |
||||
<div style="padding-bottom: 20px">用户名: <input name="username" value=""></div> |
||||
<div style="padding-bottom: 20px">密码: <input name="password" value=""></div> |
||||
<button type="submit">登录</button> |
||||
</form> |
||||
|
||||
<p style="color: red;font-weight: bold" th:text="${{session.msg}}"></p> |
||||
</body> |
||||
</html> |
@ -0,0 +1,2 @@ |
||||
server: |
||||
port: 8081 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,23 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>登录页</title> |
||||
<style> |
||||
button { |
||||
margin-left: 5px; |
||||
} |
||||
</style> |
||||
|
||||
</head> |
||||
<body> |
||||
<h2>欢迎来到登录页面</h2> |
||||
<form action="/login" method="post"> |
||||
<div style="padding-bottom: 20px">用户名: <input name="username" value=""></div> |
||||
<div style="padding-bottom: 20px">密码: <input name="password" value=""></div> |
||||
<button type="submit">登录</button> |
||||
</form> |
||||
|
||||
<p style="color: red;font-weight: bold" th:text="${{session.msg}}"></p> |
||||
</body> |
||||
</html> |
@ -0,0 +1,20 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<parent> |
||||
<groupId>cc.bnblogs</groupId> |
||||
<artifactId>use-cookie-sso</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
|
||||
<artifactId>sso-main</artifactId> |
||||
|
||||
<properties> |
||||
<maven.compiler.source>8</maven.compiler.source> |
||||
<maven.compiler.target>8</maven.compiler.target> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
</properties> |
||||
|
||||
</project> |
@ -0,0 +1,28 @@ |
||||
package cc.bnblogs; |
||||
|
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.web.client.RestTemplate; |
||||
|
||||
/** |
||||
* @description: 网站首页 |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 15:40 |
||||
*/ |
||||
@SpringBootApplication |
||||
public class MainApplication { |
||||
public static void main(String[] args) { |
||||
SpringApplication.run(MainApplication.class,args); |
||||
} |
||||
|
||||
/** |
||||
* RestTemplate是由Spring框架提供的一个可用于应用中调用rest服务的类它简化了与http服务的通信方式 |
||||
* 需要手动将RestTemplate注入到Bean容器中 |
||||
* @return |
||||
*/ |
||||
@Bean |
||||
public RestTemplate restTemplate() { |
||||
return new RestTemplate(); |
||||
} |
||||
} |
@ -0,0 +1,48 @@ |
||||
package cc.bnblogs.controller; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Controller; |
||||
import org.springframework.web.bind.annotation.CookieValue; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.client.RestTemplate; |
||||
import org.thymeleaf.util.StringUtils; |
||||
|
||||
import javax.servlet.http.Cookie; |
||||
import javax.servlet.http.HttpSession; |
||||
import java.util.Map; |
||||
|
||||
|
||||
/** |
||||
* @description: 网站主页 |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 16:12 |
||||
*/ |
||||
@Controller |
||||
@RequestMapping("/view") |
||||
public class ViewController { |
||||
|
||||
@Autowired |
||||
private RestTemplate restTemplate; |
||||
|
||||
private final String LOGIN_INFO_ADDR = "http://login.codeshop.com:8081/login/info?token="; |
||||
@GetMapping("/index") |
||||
/** |
||||
* 跳转到index.html |
||||
* 没有登录的时候没有cookie值,所以required要设为false |
||||
*/ |
||||
public String toIndex(@CookieValue(required = false,value = "TOKEN")Cookie cookie, |
||||
HttpSession httpSession) { |
||||
if (cookie != null) { |
||||
String token = cookie.getValue(); |
||||
if (!StringUtils.isEmpty(token)) { |
||||
// 访问/login/info接口时带上token请求登录用户信息
|
||||
Map result = restTemplate.getForObject(LOGIN_INFO_ADDR + token, |
||||
Map.class); |
||||
// 保存登录用户
|
||||
httpSession.setAttribute("loginUser",result); |
||||
} |
||||
} |
||||
return "index"; |
||||
} |
||||
} |
@ -0,0 +1,2 @@ |
||||
server: |
||||
port: 8082 |
@ -0,0 +1,23 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>首页</title> |
||||
</head> |
||||
<body> |
||||
<h1>欢迎来到codeshop首页</h1> |
||||
<p th:unless="${session.loginUser==null}"> |
||||
<span style="color: deepskyblue;" th:text="${session.loginUser.username}"></span> 已登录 |
||||
</p> |
||||
|
||||
<span> |
||||
<a th:if="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/login?target=http://www.codeshop.com:8082/view/index">登录</a> |
||||
<a th:unless="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/logout?target=http://www.codeshop.com:8082/view/index">退出</a> |
||||
</span> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,2 @@ |
||||
server: |
||||
port: 8082 |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,23 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>首页</title> |
||||
</head> |
||||
<body> |
||||
<h1>欢迎来到codeshop首页</h1> |
||||
<p th:unless="${session.loginUser==null}"> |
||||
<span style="color: deepskyblue;" th:text="${session.loginUser.username}"></span> 已登录 |
||||
</p> |
||||
|
||||
<span> |
||||
<a th:if="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/login?target=http://www.codeshop.com:8082/view/index">登录</a> |
||||
<a th:unless="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/logout?target=http://www.codeshop.com:8082/view/index">退出</a> |
||||
</span> |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body> |
||||
</html> |
@ -0,0 +1,20 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<parent> |
||||
<groupId>cc.bnblogs</groupId> |
||||
<artifactId>use-cookie-sso</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
|
||||
<artifactId>sso-vip</artifactId> |
||||
|
||||
<properties> |
||||
<maven.compiler.source>8</maven.compiler.source> |
||||
<maven.compiler.target>8</maven.compiler.target> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
</properties> |
||||
|
||||
</project> |
@ -0,0 +1,22 @@ |
||||
package cc.bnblogs; |
||||
|
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.web.client.RestTemplate; |
||||
|
||||
/** |
||||
* @description: |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 15:42 |
||||
*/ |
||||
@SpringBootApplication |
||||
public class VipApplication { |
||||
public static void main(String[] args) { |
||||
SpringApplication.run(VipApplication.class,args); |
||||
} |
||||
@Bean |
||||
public RestTemplate restTemplate() { |
||||
return new RestTemplate(); |
||||
} |
||||
} |
@ -0,0 +1,40 @@ |
||||
package cc.bnblogs.controller; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Controller; |
||||
import org.springframework.web.bind.annotation.CookieValue; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.client.RestTemplate; |
||||
import org.thymeleaf.util.StringUtils; |
||||
|
||||
import javax.servlet.http.Cookie; |
||||
import javax.servlet.http.HttpSession; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* @description: |
||||
* @author: zfp@bnblogs.cc |
||||
* @date: 2023/3/12 16:17 |
||||
*/ |
||||
@Controller |
||||
@RequestMapping("/view") |
||||
public class ViewController { |
||||
@Autowired |
||||
private RestTemplate restTemplate; |
||||
|
||||
private final String LOGIN_INFO_ADDR = "http://login.codeshop.com:8081/login/info?token="; |
||||
|
||||
@GetMapping("/index") |
||||
public String toIndex(@CookieValue(required = false,value = "TOKEN")Cookie cookie, |
||||
HttpSession httpSession) { |
||||
if (cookie != null) { |
||||
String token = cookie.getValue(); |
||||
if (!StringUtils.isEmpty(token)) { |
||||
Map result = restTemplate.getForObject(LOGIN_INFO_ADDR + token, Map.class); |
||||
httpSession.setAttribute("loginUser",result); |
||||
} |
||||
} |
||||
return "index"; |
||||
} |
||||
} |
@ -0,0 +1,2 @@ |
||||
server: |
||||
port: 8083 |
@ -0,0 +1,18 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>vip系统</title> |
||||
</head> |
||||
<body> |
||||
<h1>这里是Vip系统</h1> |
||||
<p th:unless="${session.loginUser==null}"> |
||||
<span style="color: deepskyblue;" th:text="${session.loginUser.username}"></span> 已登录 |
||||
</p> |
||||
|
||||
<span> |
||||
<a th:if="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/login?target=http://vip.codeshop.com:8083/view/index">登录</a> |
||||
<a th:unless="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/logout?target=http://vip.codeshop.com:8083/view/index">退出</a> |
||||
</span> |
||||
</body> |
||||
</html> |
@ -0,0 +1,2 @@ |
||||
server: |
||||
port: 8083 |
Binary file not shown.
Binary file not shown.
@ -0,0 +1,18 @@ |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8"> |
||||
<title>vip系统</title> |
||||
</head> |
||||
<body> |
||||
<h1>这里是Vip系统</h1> |
||||
<p th:unless="${session.loginUser==null}"> |
||||
<span style="color: deepskyblue;" th:text="${session.loginUser.username}"></span> 已登录 |
||||
</p> |
||||
|
||||
<span> |
||||
<a th:if="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/login?target=http://vip.codeshop.com:8083/view/index">登录</a> |
||||
<a th:unless="${session.loginUser==null}" href="http://login.codeshop.com:8081/view/logout?target=http://vip.codeshop.com:8083/view/index">退出</a> |
||||
</span> |
||||
</body> |
||||
</html> |
Loading…
Reference in new issue